我正在运行以下代码,
function Person(){}
var person1 = new Person();
Person.prototype= {
name : "Ann",
sayName : function(){
console.log( this.name);
}
}
person1.sayName();
它将显示错误“对象#没有方法'sayName'”。这会导致错误,因为person1指向的原型不包含该名称的属性。 我的问题是当我改变我定义原型的方式如下:
function Person(){}
var person1 = new Person();
Person.prototype.name = "Ann";
Person.prototype.sayName = function(){
console.log(this.name);
}
person1.sayName();
它与“Ann”正确运行。谁能告诉我为什么会这样?谢谢。
答案 0 :(得分:6)
当你实例化一个"类"使用new Person
,将为新对象分配Person.prototype
的值,例如类似的东西:
person1.__proto__ = Person.prototype
(不是,仅用于说明目的。)
这意味着person1.__proto__
和Person.prototype
指向同一个对象。
如果你然后用Person.prototype
完全替换 Person.prototype = { ... }
,那么实例的原型和类原型就不再指向同一个对象了。
但是,如果您使用Person.prototype.name = ...
修改现有原型,则两者都会继续指向相同(现在已修改)的对象。
答案 1 :(得分:0)
因为在person1
的实例化时,原型扩展尚未被评估,换句话说 - 在原型声明之后重新排序person1
的实例
function Person(){}
var person1 = new Person();
Person.prototype= {
name : "Ann",
sayName : function(){
console.log( this.name);
}
}
var person2 = new Person();
// person1.sayName(); // fails
person2.sayName(); // works
答案 2 :(得分:0)
在第一种情况下,您将Person声明为函数。然后,您将创建一个名为person1的实例,该实例继承Person.prototype。然后,您将Person.prototype设置为新对象,因此person1.prototype和Person.prototype现在引用不同的对象。然后你尝试做.sayName()并且它不起作用,因为person1.prototype仍然是空的。
在第二种情况下,您只需设置属性,而不是重新定义Person.prototype。这样,person1对原型的引用仍然与Person.prototype相同,这就是为什么当你执行.sayName()时它的工作原理。
如果移动var person1 = new Person();在设置原型之后,第一个选项也将起作用,因为person1将继承对Person.prototype的新引用而不是旧引用。