javascript中的原型行为

时间:2013-06-18 21:49:24

标签: javascript prototype-programming function-prototypes prototype-oriented

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

为什么 a.toString 在打印“秒”的 b.toString 时仍会打印“frist”。 任何人都可以解释我在这里缺少的东西。

3 个答案:

答案 0 :(得分:2)

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

当您致电new A()时,会发生这种情况:

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

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

因此,当您覆盖A.prototype时,a.__proto__仍然会链接到旧的A.prototype,就像您期望的那样 代码:

var A = 10, a, b;

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

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

如果要输入less,只需存储对原型的引用:

function A() {

}
var fn = A.prototype;

fn.toString = function() {

};

fn.valueOf = function() {

};

fn.toJSON = function() {

};

答案 1 :(得分: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

答案 2 :(得分:0)

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

实际上,创建对象后,除了非标准__proto__ property之外,您无法分配不同的[[Prototype]]

修改

只是为了说清楚:

// 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 继承自新对象,因为它是在更改后创建(实例化)的。