user1187135
user1187135

Reputation:

Still confused with js Prototype

I am confused with what prototype actually does. I am learning HTML canvas right now and for one of the examples, it uses prototype to declare the draw method. But whats the difference between using prototype versus simply putting it in the constructor function itself?

Isn't this example from the book:

function Ball (radius, color) {
    if (radius === undefined) { radius = 40; }
    if (color === undefined) { color = "#ff0000"; }
    this.x = 0;
    this.y = 0;
    this.radius = radius;
    this.rotation = 0;
    this.scaleX = 1;
    this.scaleY = 1;
    this.color = utils.parseColor(color);
    this.lineWidth = 1;
    }


Ball.prototype.draw = function (context) {
context.save();
context.translate(this.x, this.y);
context.rotate(this.rotation);
context.scale(this.scaleX, this.scaleY);
context.lineWidth = this.lineWidth;
context.fillStyle = this.color;
context.beginPath();
//x, y, radius, start_angle, end_angle, anti-clockwise
context.arc(0, 0, this.radius, 0, (Math.PI * 2), true);
context.closePath();
context.fill();
if (this.lineWidth > 0) {
context.stroke();
}
context.restore();
};

The same as putting this in?:

function Ball(radius, color){
...
this.draw = function (context) {
    context.save();
    context.translate(this.x, this.y);
    context.rotate(this.rotation);
    context.scale(this.scaleX, this.scaleY);
    context.lineWidth = this.lineWidth;
    context.fillStyle = this.color;
    context.beginPath();
    //x, y, radius, start_angle, end_angle, anti-clockwise
    context.arc(0, 0, this.radius, 0, (Math.PI * 2), true);
    context.closePath();
    context.fill();
    if (this.lineWidth > 0) {
    context.stroke();
    }
    context.restore();
    };
}

Upvotes: -1

Views: 103

Answers (2)

sedran
sedran

Reputation: 3566

there is not too much difference. The main difference is that, methods created via prototype can't access to the private members of the object.

function Ball (radius, color) {
    if (radius === undefined) { radius = 40; }
    if (color === undefined) { color = "#ff0000"; }
    this.x = 0;
    this.y = 0;
    this.radius = radius;
    this.rotation = 0;
    this.scaleX = 1;
    this.scaleY = 1;
    this.color = utils.parseColor(color);
    this.lineWidth = 1;
    var privateVar = 0;
    function privateFunction() {
        // anything
    }
}

Ball.prototype.draw = function() {
   privateFunction(); // doesn't work.
   privateVar = 2; // doesn't work
   this.lineWidth = 2; // this will work.
};

Upvotes: 1

xiaowl
xiaowl

Reputation: 5207

prototype is an Object shared by all other objects who take it as prototype, which results in that methods added to prototype dynamically can be shared by all instances.

function ClassA(){
    this.sayHello = function(){
        return "hello!";
    }
}

var instanceA = new ClassA();
instanceA.sayHello();//return "hello!";
//add a method to instanceA
instanceA.sayBye = function(){ return "Bye!"; }

var instanceB = new ClassA();
instanceB.sayBye(); //error, sayBye is not a method of instanceB.

//But, this really works
ClassA.prototype.sayBye = function(){ return "Bye!"; }

And, since all instance share the single prototype, all methods only stay in one place in memory. In your second implementation, each instance has its own method, which resulting in a lot of memory using.

Keeping method out of the definition of Class makes code more clean and readable, although this is not a strong evidence .

With prototype, it's more easy for developers to write code in OOP style.

 function ClassB(){
 }
 ClassB.prototype = new ClassA();
 // The equivalent approach may be this
 function ClassB(){
     ClassA.apply(this);
 }

Both of the two approaches can do the same jobs, so choose any one you like.

Upvotes: 2

Related Questions