Я играл с классами и подклассами в Javascript, и я подумал, что попробую, что кажется простым примером: класс Circle
, который инициализируется cx
, cy
, (координаты начала координат) и r
(размер радиуса). Я также передаю ссылку на SVG. Тогда круг рисует себя на конкретизации, например:Использование методов для вычисления параметров конструктора в производном классе в JS
let c = new Circle(svg, 100, 100, 10);
До сих пор так хорошо, это определение класса работает:
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);
}
}
Теперь для подклассов. Я полагал, что хорошее место для метода .random(n)
бы на RandomCircle
классе, поэтому я попытался это:
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)
}
}
выглядит довольно хорошо, не работает, по-видимому, потому, что вы не можете обратиться к this
перед вызовом super
. Итак, мое затруднение: что мне делать, если я хочу использовать методы класса для вычисления параметров для перехода к super()
в производном классе?
<!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>
Мой главный вопрос, почему это классный метод? Для этого, по крайней мере, эта функция легко может быть автономной функцией. – loganfsmyth
Возможно, так, в этом случае. Но наверняка в какой-то момент полезно использовать методы класса для вычисляемых параметров конструктора для расширенных классов. – pat
Методы имеют доступ к свойствам экземпляра, которые предположительно не инициализируются перед вызовом конструктора - это один аргумент против использования методов класса в этом случае. – artem