Domanda

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.

È stato utile?

Soluzione

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() {

};

Altri suggerimenti

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

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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top