(简单的解释)
prototype 属性仅在使用 function 作为构造函数时适用(通过使用 new 运算符)。 function 创建它的 prototype 的克隆,并且函数内的 this 关键字设置为克隆。克隆上的属性是对prototypes 属性的直接引用/指针。
对象字面量{} 是new Object() 的更强大的替代表达式,因此“继承”Object.prototype 的属性。
所以:
function ClassLike() {}
ClassLike.prototype = {
foo : "bar"
}
var instance = new ClassLike();
alert( instance.foo ); // bar
之所以有效,是因为 new 运算符会启动一些操作以创建一个新对象,而:
var instance = {
foo : "bar"
}
instance.prototype = {
baz : "foobar"
}
仅向已创建的对象添加另一个属性(原型),并没有启动任何过程来实际分配/更改对象的原始原型。
现在 Mozilla 已经添加了一种非标准(IE 不支持)方式来通过__proto__ 更改已经实例化的对象原型,并且有一些请求将其添加到 ES5(EcmaScript 5)。我不会在自动取款机上使用它。但它的工作原理是这样的:
var instance = {};
var parent = {
foo : "bar"
}
instance.__proto__ = parent;
alert( instance.foo ); // bar
另一种更改已实例化对象原型的方法是添加到Object 构造函数原型(由于许多原因不建议这样做)。因此:
var instance = {}; // a more powerful alternative to `new Object()`
Object.prototype.foo = "bar";
alert( instance.foo ); // bar
这一切皆有可能,尽管这样做是否明智……我会说不,但意见各不相同,我宁愿避免争论;)
无论如何,只要记住prototype 属性在new 和function 上起作用,否则它只会成为实例上的属性。