user3674318
user3674318

Reputation: 91

Why the different way to add prototype affects?

I was I running the following code,

function Person(){}
var person1 = new Person();
Person.prototype= {
    name : "Ann",
    sayName : function(){
        console.log( this.name);
    }
}
 person1.sayName();

it will show an error "Object # has no method 'sayName'". This cause en error because the prototype that person1 points to doesn't contain a property of that name. My question is when I change the way I define the prototype as the following:

function Person(){}
var person1 = new Person();
Person.prototype.name = "Ann";
Person.prototype.sayName = function(){
    console.log(this.name);
}
person1.sayName();

It runs correctly with "Ann". Can anyone tell me why this happens? Thank you.

Upvotes: 1

Views: 80

Answers (3)

juvian
juvian

Reputation: 16068

In your first case, you are declaring Person as a function. Then you are creating an instance called person1, which inherits Person.prototype. Then you are setting Person.prototype to a new object, so person1.prototype and Person.prototype now reference different object. Then you try to do .sayName() and it does not work, as person1.prototype is still empty.

In your second case, instead of redefining Person.prototype you are just setting properties. That way, the reference that person1 has to the prototype is still the same as Person.prototype, so that´s why when you do .sayName() it works.

If you move var person1 = new Person(); to after setting the prototype the first option will also work, as person1 will inherit the new reference to Person.prototype instead of the old one.

Upvotes: 0

deceze
deceze

Reputation: 522042

When you instantiate a "class" with new Person, that new object will be assigned the value of Person.prototype, e.g. something like:

person1.__proto__ = Person.prototype

(Not really, just for illustrative purposes.)

That means both person1.__proto__ and Person.prototype point to the same object.

If you then go and completely replace Person.prototype with Person.prototype = { ... }, then the instance's prototype and the classes prototype do not point to the same object anymore.

However, if you modify the existing prototype with Person.prototype.name = ..., then both continue to point to the same (now modified) object.

Upvotes: 6

birdspider
birdspider

Reputation: 3074

because at the instantiation of person1 the prototype extensions are not evaluated yet, in other words - reorder the instatiation of person1 after the declaration of the prototype

function Person(){}

var person1 = new Person();

Person.prototype= {
    name : "Ann",
    sayName : function(){
        console.log( this.name);
    }
}

var person2 = new Person();

// person1.sayName(); // fails
person2.sayName(); // works

Upvotes: 0

Related Questions