I’ve been playing with classes and subclasses in Javascript, and I thought I’d try what seems to be a simple example: a Circle class which is initialized with cx, cy, (coordinates of the origin) and r (the size of the radius). I also pass in a reference to an SVG. Then the Circle draws itself upon instantiation, like this:
let c = new Circle(svg, 100, 100, 10);
So far so good, this class definition works:
class Circle {
  constructor(svg,r,cx,cy){
    this.svg = svg;
    this.circle = document.createElementNS("http://www.w3.org/2000/svg", "circle"); 
    this.circle.setAttribute("cx", cx);
    this.circle.setAttribute("cy", cy);
    this.circle.setAttribute("r", r);
    this.draw()
  }
  draw(){
    this.svg.appendChild(this.circle);
  }
}
Now for subclassing. I figured a good place for a .random(n) method would be on the RandomCircle class, so I tried this:
class RandomCircle extends Circle {
  constructor(svg){
    cx = this.random(svg.getAttribute('width')) // error
    cy = this.random(svg.getAttribute('height')) // error
    r = this.random(10); // error
    super(svg,cx,cy,r);
    this.draw();
  }
  random(n){
    return Math.floor(Math.random()*n) 
  }
}
Looks pretty good, doesn’t work, apparently because you can’t refer to this before calling super. So my quandary is, what do I do if I want to use class  methods to calculate parameters to pass to super() in a derived class?
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>random circles</title>
</head>
<body>
<svg style="border:1px solid black" width=500 height=500></svg>
<script>
class Circle {
  constructor(svg,r,cx,cy){
    this.svg = svg;
    this.circle = document.createElementNS("http://www.w3.org/2000/svg", "circle"); 
    this.circle.setAttribute("cx", cx);
    this.circle.setAttribute("cy", cy);
    this.circle.setAttribute("r", r);
    this.draw()
  }
  draw(){
    this.svg.appendChild(this.circle);
  }
}
class RandomCircle extends Circle {
  constructor(svg){
    cx = this.random(svg.getAttribute('width')) // error
    cy = this.random(svg.getAttribute('height')) // error
    r = this.random(10); // error
    super(svg,cx,cy,r);
    this.draw();
  }
  random(n){
    return Math.floor(Math.random()*n) 
  }
}
let svg = document.querySelector('svg');
Array(3).fill().forEach(() => new Circle(svg, 10,Math.floor(Math.random()*500),Math.floor(Math.random()*500))); // these are fine
new RandomCircle(svg); // this fails
</script>
</body>
</html>
