Reputation: 2604
Is prototype inheritance behaving differently based on the type? Is the contextual reference THIS working different in these two cases? Why in this examples, one is accessing to the prototype and the other one is creating a new property to the object?
var Player = function(){};
Player.prototype.name = '';
Player.prototype.set_name = function(name){this.name = name;}
var p1 = new Player();
var p2 = new Player();
p1.set_name('Johanna');
Value return by these two:
// Checking object properties
>p1
Player {name: "Johanna", set_name: function}
>p2
Player {name: "", set_name: function}
// Checking prototypes
>p1.__proto__
Object {name: "", set_name: function}
>p2.__proto__
Object {name: "", set_name: function}
But if I do the Player with name as an object property, the function set_name is modifying the prototype.
var Player = function(){};
Player.prototype.name = {};
Player.prototype.set_name = function(name){this.name['first_name'] = name;}
var p1 = new Player();
var p2 = new Player();
p1.set_name('Andrew');
Value return by these two:
// Checking object properties
>p1.name
Object {first_name: "Andrew"}
>p2.name
Object {first_name: "Andrew"}
// Checking prototypes
>p1.__proto__.name
Object {first_name: "Andrew"}
>p2.__proto__.name
Object {first_name: "Andrew"}
Why is this happening? What concept(s) am I missing?
Upvotes: 1
Views: 100
Reputation: 239443
Inheritance chain
When you create an object with a constructor function, the inheritance chain goes like this, for lookup.
The current object will be searched.
Prototype of the parent will be searched.
Prototype of the parent's parent will be searched.
...
And finally the global object will be searched. If it is not found anywhere, undefined
will be returned. If the value being looked up is found in any of these levels, it will be returned immediately.
Note: Assignments won't go up the inheritance chain. If you assign a value to an attribute of an object (if it is not present it will be created) then the value will be assigned to that attribute.
First case:
You are doing
this.name = name;
So,
p1.set_name('Andrew');
creates a new name
attribute in p1
and stores Andrew
in it. And when you tried to print p1
, the name was looked up on p1
and it was found in p1
itself. So, Andrew
was returned. But, when you printed p2
, name is not found in p2
. It goes up in the hierarchy and finds the name
in parent's prototype. So, it returns the empty string.
Second case:
You are doing
this.name['first_name'] = name;
So,
p1.set_name('Andrew');
looks up name
in p1
. Because you are trying to access 'first_name'
on this.name
. So, it tries to retrieve name
attribute. It doesn't find it in p1
, so goes up and finds it in the parent's prototype. It is an empty object and name
gets assigned to first_name
attribute of that object.
We know that p2
's prototype is the same as p1
's prototype. We can confirm that like this
console.log(p1.__proto__ === p2.__proto__);
# true
So, when you look up p2
's prototype, which is the same as p1
's prototype, the name Andrew
is found.
Upvotes: 2
Reputation: 1659
As a general case variables and such are set in the constructor. For more info on the subject and a better explanation than i can do reference here: http://javascriptweblog.wordpress.com/2010/06/07/understanding-javascript-prototypes/
// Constructor
function Player() {
this.names = '';
};
// Public Method
Player.prototype.set_name = function(name){
this.name = name;
}
// Static method
Player.walk = function() {}
var player1 = new Player();
player1.set_name('John Doe'); // fires the public method
Player.walk(); // fires the static method
Upvotes: 0