0

I am confused with the following prototype behavior in javascript.

function A(){
};

A.prototype.toString = function(){
            console.log('first');
               }

var a = new A(), b;

A.prototype = {
    toString:function(){
        console.log('second');
    }
}

b = new A();

a.toString();
//outputs :  first

b.toString();
//outputs :  second

Why does a.toString still prints "frist" when compared to b.toString which prints "second". can anyone please explain what i am missing here.

2
  • Why var a = new A(), b? Commented Jun 18, 2013 at 21:58
  • @basilikum: Oh I misinterpreted, he's just declaring b as var. It's all good. Commented Jun 18, 2013 at 22:05

3 Answers 3

2

The prototype link has nothing to do with the constructor that constructed the object, it is stored on objects themselves.

When you call new A() this happens:

var a = {};
a.__proto__ = A.prototype;
A.call(a);

Note that the above is not standard syntax but does work in chrome and firefox.

So when you overwrite A.prototype, a.__proto__ is still linking to the old A.prototype as you would expect with similar code:

var A = 10, a, b;

a = A;
A = 7; //a is still 10
b = A; 

I don't recommend reassigning the prototype, because then you need to re-establish the constructor property and it requires additional level of indentation.

If you want to type less, just store reference to the prototype:

function A() {

}
var fn = A.prototype;

fn.toString = function() {

};

fn.valueOf = function() {

};

fn.toJSON = function() {

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

3 Comments

I wouldn't say "nothing", rather an object's [[Prototype]] is set to the constructor's prototype at the time the object was constructed.
@RobG that's just basically saying the same thing :P. I am just trying to dispel the belief that the constructor is out there watching all the created instances or something.
Yes, same thing but different. :-)
0

function A(){ };

A.prototype.toString = function(){
            console.log('first');
               }     // here A prints 'first'

var a = new A(), b;  

A.prototype = {    
    toString:function(){
        console.log('second');
    }
}                    // here A prints 'second'

b = new A();

a.toString();
//outputs :  first

b.toString();
//outputs :  second

Comments

0

An object's internal [[Prototype]] (the one it inherits from) is set to its constructor's prototype at the time it is constructed. Assigning a new object to the constructor's prototype does not alter the [[Prototype]] of instances that have already been created.

In fact, once an object is created, you can't assign a different [[Prototype]] other than by the non–standard __proto__ property.

Edit

Just to make it really clear:

// A simple constructor
function Person(name) {
  this.name = name;
}

// Assign a method to its default prototype
Person.prototype.showName = function() {
  return this.name;
}

// This instance will be assigned the above as its [[Prototype]]
// with its showName method
var fred = new Person('Fred');

// Assign a new object to Person.prototype 
Person.prototype = {};

// Assign a new showName method
Person.prototype.showName = function() {
  return 'My name is ' + this.name;
}

// This instance has the new object as its [[Prototype]]
var sue = new Person('Sue');

console.log(
    fred.showName() + '\n'  // Fred 
  + sue.showName()          // My name is Sue
);

It can be seen that fred still inherits from the original prototype object, sue inherits from the new object because it was created (instantiated) after the change.

2 Comments

How come this works obj = {foo:{a:1}, b:1}; function Class(){}; Class.prototype = obj; y = new Class(); y.foo.a = 2; // prints 2 x = new Class(); x.foo.a // prints 2
Because both x and y are created as instances of Class when it has the same object (obj) as its prototype, so x and y have the same [[Prototype]] (i.e. obj). If you change Class.prototype before creating x, it will inherit from the new object and will have a different [[Prototype]] to y

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.