javascript - 这是 JavaScript 原型(prototype)继承模型中的缺陷吗?

标签 javascript inheritance prototypal

我一直在从 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 the Person 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

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

关于javascript - 这是 JavaScript 原型(prototype)继承模型中的缺陷吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18435249/

相关文章:

C++派生类构造函数调用基类构造函数错误

c# - 为什么我需要接口(interface)?

javascript - 适当的原型(prototype)继承

javascript - Angularjs 1.x 中的 Typescript 继承

javascript - 如何在 Javascript crossbrowser 中删除一个对象

extjs - 动态加载javascript?

inheritance - 在 Go 中实现 Struct 抽象的正确方法是什么?

javascript - rails : how to create image thumbnails that expand when clicked?

javascript - 在 HTML 中加载/调用 javascript 的适当位置

javascript - 在 JQuery 中使用 JSON 填充 SELECT