1

我对 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

与打印“第二”的b.toString相比,为什么a.t​​oString仍然打印“第一”。谁能解释一下我在这里缺少什么。

4

3 回答 3

2

原型链接与构造对象的构造函数无关,它存储在对象本身上。

当你打电话new A()时会发生这种情况:

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

请注意,以上不是标准语法,但可以在 chrome 和 firefox 中使用。

因此,当您覆盖时A.prototypea.__proto__仍会链接到旧版本A.prototype,正如您使用类似代码所期望的那样:

var A = 10, a, b;

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

我不建议重新分配原型,因为那样你需要重新建立构造函数属性并且它需要额外的缩进级别。

如果你想输入更少,只需存储对原型的引用:

function A() {

}
var fn = A.prototype;

fn.toString = function() {

};

fn.valueOf = function() {

};

fn.toJSON = function() {

};
于 2013-06-18T21:55:16.297 回答
0

函数 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
于 2013-06-18T21:52:25.410 回答
0

一个对象的内部[[Prototype]](它继承的那个)在它被构造的时候被设置为它的构造函数的原型。将新对象分配给构造函数的原型不会改变[[Prototype]]已经创建的实例。

事实上,一旦创建了一个对象,[[Prototype]]除了通过非标准__proto__属性之外,您不能指定其他对象。

编辑

只是为了说清楚:

// 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
);

可以看出,fred还是继承了原来的原型对象,sue继承了新的对象,因为它是在变更之后创建(实例化)的。

于 2013-06-18T22:16:34.470 回答