JavaScript和原型继承

Set*_*hen 5 javascript

好像我终于理解了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"
Run Code Online (Sandbox Code Playgroud)

据我所知,使用Object.create创建继承的原型对象比使用new关键字要好得多.这引起了我脑子里的几个问题.

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

Aad*_*hah 3

回答您的问题:

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

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

我建议您阅读我的博客文章。这是关于原型继承的非常好的入门读物:Aadit M Shah | 为什么原型继承很重要