1

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?

2
  • When you add a property to the prototype it is shared with other instances. Add unique properties to the constructor. Commented Apr 4, 2014 at 6:26
  • Isn't Player.prototype.name = ''; and Player.prototype.name = {}; both using the prototype? Why using a set_name function is acting over the prototype in one case and adding a property to the object in the other case? Commented Apr 4, 2014 at 6:30

2 Answers 2

2

Inheritance chain

When you create an object with a constructor function, the inheritance chain goes like this, for lookup.

  1. The current object will be searched.

  2. Prototype of the parent will be searched.

  3. 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.

Sign up to request clarification or add additional context in comments.

1 Comment

I read about the inheritance chaining you mentioned at the beginning. I knew it but the NOTE comment you posted is the key. Thanks
0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.