【问题标题】:JavaScript and prototype inheritanceJavaScript 和原型继承
【发布时间】:2013-07-17 19:54:51
【问题描述】:

似乎我终于理解了 JavaScript 继承以及它应该如何正确完成。这是我的代码:

function Human(eyes) {
    this.eyes = eyes ? "Not blind" : "Blind";
}
Human.prototype.canSee = function () {
    return this.eyes;
};
function Male(name, eyes) {
    Human.call(this, eyes);
    this.name = name;
}
Male.prototype = Object.create(Human.prototype);
var Sethen = new Male("Sethen", true);
console.log(Sethen.canSee()); //logs "Not blind"

据我了解,使用Object.create 创建原型对象进行继承比使用new 关键字要好得多。这在我的脑海中提出了几个问题。

  1. Male.prototype = Object.create(Human.prototype) 中,原型链会是Male.prototype --> Human.prototype --> Object.prototype --> null吗?
  2. 在我使用Human.call(this, eyes); 调用超类的Male 构造函数中,我必须在Male 构造函数中再次传递眼睛,以将其传递给Human 构造函数。这似乎很痛苦,有没有更简单的方法可以做到这一点?
  3. 为什么有时我会看到像Male.prototype = new Human(); 这样的代码……这似乎是不正确的。当我们这样做时,实际发生了什么??

【问题讨论】:

标签: javascript


【解决方案1】:

回答您的问题:

  1. 没错。当您设置Male.prototype = Object.create(Human.prototype) 时,您将原型链设置为Male.prototype --> Human.prototype --> Object.prototype --> null。然后,当您创建 var Sethen = new Male 时,实例 (Sethen) 将从该原型链继承。
  2. 不,您需要手动将参数传递给基本构造函数。如果您想在Male 函数本身内设置this.eyes = eyes ? "Not blind" : "Blind",但这只是代码重复。你的做法是正确的。
  3. 那是旧的做事方式(在Object.create 标准化之前)。我建议你不要使用它。在大多数情况下,它与新方法相同。但是,使用这种方法,您还会在 Male.prototype 上获得不需要的属性,例如 eyes

当我们执行Male.prototype = new Human 时,我们会创建一个Human 的新实例并将其分配给Male.prototype。因此原型链是Male.prototype --> Human.prototype --> Object.prototype --> null。然而,我们也得到了我们不需要的属性Male.prototype.eyes。那应该只属于Male的实例。

我建议您阅读我的博客文章。这是一个非常好的原型继承入门:Aadit M Shah | Why Prototypal Inheritance Matters

【讨论】:

  • 谢谢你!这为我清除了一切。我假设我们也得到了一些不需要的属性,例如 eyes,但不确定。
  • 在使用 Object.create 辅助函数之前:stackoverflow.com/questions/16063394/…(如果您想支持 IE 8,仍然可以使用)在这些辅助函数中,也可以在设置继承后将构造函数设置为正确的函数。如果您打算使用 constructor 属性,您仍然需要这样做。
  • @HMR 啊。好吧,我现在使用的唯一辅助函数是augment。它使用Object.create,但您也可以不使用Object.create 来实现它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-16
  • 2010-09-28
  • 2018-02-21
  • 1970-01-01
相关资源
最近更新 更多