3

我一直在从 John Resig 的JavaScript Ninja 的秘密中学习 JavaScript 中的原型继承,我想知道在下面的代码示例(我刚刚编造的)中会发生什么。

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该属性/方法swingSwordPerson实例?如果不是,那么Ninja引用原型对象的原型属性如何既引用Person实例具有swingSword属性?

4

1 回答 1

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确实有 a swingSword,则可能意味着它是在prototype更改之前创建的。

对象从创建之时起就保留自己的[[Prototype]]引用,而不管对其构造函数的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

每个示例:http: //jsfiddle.net/G8uTk/

于 2013-08-26T01:00:35.570 回答