我一直在学习JavaScript中的原型继承来自John Resig的 JavaScript Ninja的秘密,我想知道下面的代码示例(我刚刚编写的)会发生什么。
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
对象,通过其原型,它具有swingSword
方法,通过Person
原型的原型继承,有sayHello
方法。
我感到困惑的地方如下:因为属性swingSword
(恰好是一个方法)附加到Ninja
的原型之前人员实例被分配给Ninja
的原型,swingSword
属性/方法不会被后来的Person
实例赋值覆盖吗?如果没有,那么引用原型对象的Ninja
原型属性如何引用Person
实例,和都有swingSword
属性?
答案 0 :(得分:4)
[...]通过它的原型,有
swingSword
方法,[...]
虽然该陈述的其余部分是正确的 - ninja1
引用Ninja
(从技术上讲,Ninja.prototype
)并且将通过继承进行sayHello
- 您的关于swingSword
以后的想法是正确的。
swingSword
实例的后期分配不会覆盖Person
属性/方法吗?
在您的代码段末尾,ninja1.swingSword
应为undefined
。
console.log(typeof ninja1.swingSword); // 'undefined'
// as is:
console.log(typeof Ninja.prototype.swingSword); // 'undefined'
在Ninja.prototype = ...
之后,prototype
所附加的原始swingSword
对象不再被引用。因此,在创建新实例时不会使用它。
如果您打算设置一个新的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