我一直在从 John Resig 的 JavaScript Ninja 的 secret 中学习 JavaScript 中的原型(prototype)继承,并且我想知道以下代码示例(我刚刚编写的)中会发生什么。
function Person() {}
Person.prototype.sayHello = function() {
alert("Hello World");
}
function Ninja() {}
Ninja.prototype.swingSword = function() {
alert("I can swing my sword.");
}
Ninja.prototype = new Person();
var ninja1 = new Ninja();
据我所知,所有这些代码行的结果是变量 ninja1
引用 Ninja
对象,通过其原型(prototype),具有 swingSword
方法,并通过 Person
的原型(prototype)继承的原型(prototype),有 sayHello
方法。
我感到困惑的地方在于:因为属性 swingSword
(恰好是一种方法)附加到 Ninja
的原型(prototype) before person 实例被分配给 Ninja
的原型(prototype),不会是 swingSword
属性/方法被后来的 Person
赋值覆盖实例?不然怎么能Ninja
的原型(prototype)属性,引用原型(prototype)对象,同时引用 Person
例如,和 有一个 swingSword
属性(property)?
最佳答案
[...] that through its prototype, has the
swingSword
method, [...]
虽然该陈述的其余部分是正确的——ninja1
引用了 Ninja
(嗯,从技术上讲,Ninja.prototype
)并且将具有通过继承的 sayHello
-- 你后来对 swingSword
的想法是正确的。
wouldn't the
swingSword
property/method be overwritten by the later assignment of thePerson
instance?
在代码段的末尾,ninja1.swingSword
应该是 undefined
。
console.log(typeof ninja1.swingSword); // 'undefined'
// as is:
console.log(typeof Ninja.prototype.swingSword); // 'undefined'
在 Ninja.prototype = ...
之后,不再引用 swingSword
附加到的原始 prototype
对象。因此,在创建新实例时不会使用它。
如果您打算设置一个新的 prototype
对象,您需要确保在修改它之前已经完成。
Ninja.prototype = new Person();
Ninja.prototype.swingSword = function() {
alert("I can swing my sword.");
}
var ninja1 = new Ninja();
console.log(typeof ninja1.swingSword); // 'function'
而且,如果 ninja1
确实有一个 swingSword
,这可能意味着它是在 prototype
更改之前创建的。
对象保留自己的[[Prototype]]
reference从创建它们开始,无论对其构造函数的 prototype
属性进行了哪些更改。
Ninja.prototype.swingSword = function() {
alert("I can swing my sword.");
}
var ninja1 = new Ninja();
Ninja.prototype = new Person(); // won't affect existing instances
var ninja2 = new Ninja();
console.log(typeof ninja1.swingSword); // function
console.log(typeof ninja2.swingSword); // undefined
关于javascript - 这是 JavaScript 原型(prototype)继承模型中的缺陷吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18435249/