变量属性的继承 [英] Inheritence of variable properties

查看:94
本文介绍了变量属性的继承的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

来自codeacademy的练习:

From an exercise at codeacademy:

function Penguin(name) {
    this.name = "Pingy";
    this.numLegs = 2;
}

// create your Emperor class here and make it inherit from Penguin
function Emperor (name){
    this.name = name;
}
Emperor.prototype = new Penguin();
var emp = new Emperor("Empy");

所以我做了 Emperor 从<继承属性code> Penguin ,现在我知道 emp.numLegs 将是2。

So I made Emperor inherit properties from Penguin, now I know that emp.numLegs will be 2.

阅读评论后,我编辑了这个问题:
如你所见,我在创建 emp emp时给出了一个名字。 name 确实是我的新emp的名字,即Empy。但是从Penguin类构造函数继承的名称呢?它去哪了?

After reading the comments I edited the question: As you can see I gave a name upon creating emp, and emp.name will indeed be the name of my new emp, which is "Empy". But what about the name inherited from the Penguin class constructor? Where does it go?

推荐答案

Codecademy是初学者学习JavaScript的好方法。学习任何编程语言都需要练习,而Codecademy会让你练习。

Codecademy is a great way for beginners to learn JavaScript. Learning any programming language takes practice, and Codecademy makes you practice.

有时你需要超越实践的范围并学习一些理论。阅读以下答案。它很好地解释了JavaScript中的原型继承: https://stackoverflow.com/a/8096017/783743

Sometimes however you need to go beyond the scope of the practicals and learn some theory. Read the following answer. It explains prototypal inheritance in JavaScript really well: https://stackoverflow.com/a/8096017/783743

现在你有一个 Penguin 构造函数,如下所示:

Now you have a Penguin constructor as follows:

function Penguin(name) {
    this.name = name;
    this.numLegs = 2;
}

然后你创建一个 Emperor 继承自 Penguin的构造函数

Then you create an Emperor constructor which inherits from Penguin:

function Emperor(name) {
    this.name = name;
}

Emperor.prototype = new Penguin();

请注意,您正在创建一个 Penguin 并将其分配给 Emperor.prototype 。因此:

Notice that you're creating an instance of Penguin and assigning it to Emperor.prototype. Hence:


  1. Emperor.prototype.name = undefined - 这是因为你'不要将任何名称传递给 Penguin 构造函数。如果我写了 Emperor.prototype = new Penguin(Empy)那么 Emperor.prototype.name 将是Empy

  2. Emperor.prototype.numLegs = 2 - 显然。

  1. Emperor.prototype.name = undefined - this is because you're not passing any name to the Penguin constructor. If I'd written Emperor.prototype = new Penguin("Empy") then Emperor.prototype.name would be "Empy".
  2. Emperor.prototype.numLegs = 2 - obviously.

现在当您按如下方式创建新的 Emperor 时,您需要提供构造函数名称(请记住,您从 Penguin 继承 undefined 作为名称)。因此:

Now when you create a new Emperor as follows you need to give the constructor a name (remember that you're inheriting undefined from Penguin as a name). Hence:

var emp = new Emperor("Empy");

这是旧学校的方法。

现在JavaScript程序员使用 Object.create 调用继承另一个构造函数。让我用一个例子来解释:

Nowadays JavaScript programmers use Object.create and call to inherit from another constructor. Let me explain with an example:

function Emperor(name) {
    Penguin.call(this, name);
}

Emperor.prototype = Object.create(Penguin.prototype);
Emperor.prototype.constructor = Emperor;

这种方法比旧学校方法有几个优点:

This method has several advantages over the old school method:


  1. 而不是使用新企鹅() Penguin 的新实例>并且不传递任何参数,我们使用 Object.create(Penguin.prototype)继承 Penguin 的原型成员 。这也可以防止在实际调用派生构造函数之前对基础构造函数进行不必要的初始化。

  2. 而不是编写 this.name = name in我们再次使用 Penguin.call(this,name)为我们调用基础构造函数。这种模式称为mixin,如果基本构造函数需要在运行时初始化或需要维护自己的状态信息,则非常有用。

  1. Instead of creating a new instance of Penguin using new Penguin() and passing no arguments to it, we inherit the prototype members of Penguin using Object.create(Penguin.prototype). This also prevent unnecessary initialization of the base constructor until the derived constructor is actually called.
  2. Instead of writing this.name = name in the derived constructor again we call the base constructor using Penguin.call(this, name) which does it for us. Such a pattern is called a mixin and is very useful if the base constructor needs to be initialized at runtime or needs to maintain its own state information.

请注意,我们还添加了一个附加语句 Emperor.prototype.constructor = Emperor 。这是因为 prototype 是一个非常特殊的属性,存在于所有函数中。它指向一个具有非常特殊的构造函数属性的对象,该属性指向函数本身。通过将 Emperor.prototype 设置为其他内容,我们会丢失此属性。因此我们再次设置它。

Note that we have also added an additional statement Emperor.prototype.constructor = Emperor. This is because prototype is a very special property which exists on all functions. It points to an object which has a very special constructor property which points to the function itself. By setting Emperor.prototype to something else we lose this property. Hence we set it again.

这两个例子中的净效果是相同的。但是对于更复杂的代码,使用新方法要好得多。快乐学习JavaScript。

The net effect in both these examples is the same. However for more complex code it's much better to use the new method. Happy learning JavaScript.

这篇关于变量属性的继承的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆