Proto.md 2.6 KB

Прототипное ООП.

Идея.

Прототипное ООП в JS базируется на простой идее, которую следует запомнить: каждый объект имеет прототип, т. е. другой объект, в котором ищуться поля в случае отсутствия их в оригинальном объекте:

    var a = {};
    a.toString() // "[object Object]"
    a.__proto__ // Object {}
    a.__proto__.constructor // function Object() { [native code] }

a.toString() отсутствует как явно определенный в объекте a, однако он найден в прототипе Object.

function 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 обычно реализуется в два этапа - создание одного объекта с прототипом предка, насыщение его общими и статическими методами этого класса, после чего использование этого объекта в качестве прототипа для объектов класса:

function 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";

Пример

http://canvas.asmer.fe.a-level.com.ua/