Прототипное ООП в JS базируется на простой идее, которую следует запомнить: каждый объект имеет прототип, т. е. другой объект, в котором ищуться поля в случае отсутствия их в оригинальном объекте:
|> click here to run code var a = {};
a.toString() // "[object Object]"
a.__proto__ // Object {}
a.__proto__.constructor // function Object() { [native code] }
a.toString()
отсутствует как явно определенный в объекте a
, однако он найден в прототипе Object
.
|> click here to run codefunction Drawable(){
Drawable.addInstance(this);
}
Drawable.prototype.draw = function(){};
Drawable.instances = [];
Drawable.addInstance = function(item){
Drawable.instances.push(item);
}
Drawable.drawAll = function(){
for(var i = 0; i<Drawable.instances.length;i++){
Drawable.instances[i].draw();
}
}
Определенные в прототипе поля являются статическими (общими) для класса, так как у всех объектов класса есть один объект-прототип. При этом они
работают как методы каждого объекта, если используют this
, являющийся ссылкой на конкретный объект.
Наследование в JS обычно реализуется в два этапа - создание одного объекта с прототипом предка, насыщение его общими и статическими методами этого класса, после чего использование этого объекта в качестве прототипа для объектов класса:
|> click here to run codefunction Circle(x,y,radius,color){
Drawable.apply(this);
this.coords = {x: x || 0, y: y || 0}
this.radius = radius || 10;
this.color = color || "red";
}
Circle.prototype = Object.create(Drawable.prototype);
Circle.prototype.constructor = Circle;
Circle.prototype.draw = function(){
console.log('DRAW');
ctx.beginPath();
ctx.arc(this.coords.x, this.coords.y, this.radius, 0, 2 * Math.PI, false);
ctx.fillStyle = this.color;
ctx.closePath()
ctx.fill();
}
Circle.prototype.coords = {x: null, y: null};
Circle.prototype.radius = null;
Circle.prototype.color = "black";