简体   繁体   English

JavaScript和原型继承

[英]JavaScript and prototype inheritance

It seems as though I am finally understanding JavaScript inheritance and how it should be done properly. 好像我终于理解了JavaScript继承以及如何正确地完成它。 Here is my code: 这是我的代码:

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"

From what I understand, using Object.create to create your prototype object for inheritance is much better than using the new keyword. 据我所知,使用Object.create创建继承的原型对象要比使用new关键字好得多。 This raises a couple questions in my head. 这引起了我脑子里的几个问题。

  1. In the Male.prototype = Object.create(Human.prototype) would the prototype chain be Male.prototype --> Human.prototype --> Object.prototype --> null ? Male.prototype = Object.create(Human.prototype) ,原型链是Male.prototype --> Human.prototype --> Object.prototype --> null
  2. In the Male constructor where I use Human.call(this, eyes); Male构造函数中,我使用Human.call(this, eyes); to call a super class, I have to pass eyes again in the Male constructor to pass it to the Human constructor. 要调用超类,我必须在Male构造函数中再次传递眼睛,将其传递给Human构造函数。 This seems like a pain, is there an easier way to do this? 这似乎很痛苦,有没有更简单的方法呢?
  3. How come sometimes I see code like Male.prototype = new Human(); 为什么我有时会看到像Male.prototype = new Human(); ... This seems to be incorrect. ......这似乎是不正确的。 What is actually happening when we do that?? 当我们这样做时,实际发生了什么?

To answer your questions: 回答你的问题:

  1. That's correct. 那是对的。 When you set Male.prototype = Object.create(Human.prototype) you set the prototype chain as Male.prototype --> Human.prototype --> Object.prototype --> null . 设置Male.prototype = Object.create(Human.prototype) ,将原型链设置为Male.prototype --> Human.prototype --> Object.prototype --> null Then when you create var Sethen = new Male the instance ( Sethen ) inherits from this prototype chain. 然后,当您创建var Sethen = new Male ,实例( Sethen )继承Sethen原型链。
  2. No, you need to manually pass the parameters to the base constructor function. 不,您需要手动将参数传递给基础构造函数。 If you want to could set this.eyes = eyes ? "Not blind" : "Blind" 如果你想设置this.eyes = eyes ? "Not blind" : "Blind" this.eyes = eyes ? "Not blind" : "Blind" within the Male function itself but that would just be code duplication. this.eyes = eyes ? "Not blind" : "Blind" Male功能本身内的this.eyes = eyes ? "Not blind" : "Blind" ,但这只是代码重复。 What you're doing is correct. 你正在做的是正确的。
  3. That was the old way of doing things (before Object.create was standardized). 这是旧的做事方式(在Object.create标准化之前)。 I would recommend that you don't use it. 我建议你不要使用它。 For most cases it's the same as the new method. 对于大多数情况,它与新方法相同。 However using this method you also get unwanted properties like eyes on Male.prototype . 但是使用这种方法你也可以得到不想要的属性,如eyesMale.prototype

When we do Male.prototype = new Human we create a new instance of Human and assign it to Male.prototype . 当我们这样做Male.prototype = new Human ,我们创造的新实例Human并将其分配给Male.prototype Hence the prototype chain is Male.prototype --> Human.prototype --> Object.prototype --> null . 因此原型链是Male.prototype --> Human.prototype --> Object.prototype --> null However we also get the property Male.prototype.eyes which we don't require. 但是我们也得到了我们不需要的属性Male.prototype.eyes That should only belong to the instance of Male . 这应该只属于Male的例子。

I would recommend you read my blog post. 我建议你阅读我的博文。 It's a really good primer on prototypal inheritance: Aadit M Shah | 这是关于原型继承的一个非常好的入门: Aadit M Shah | Why Prototypal Inheritance Matters 为什么原型继承很重要

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM