变量属性的继承 [英] Inheritence of variable properties
问题描述
来自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 $ c $的实例c>并将其分配给
Emperor.prototype
。因此:
Notice that you're creating an instance of Penguin
and assigning it to Emperor.prototype
. Hence:
-
Emperor.prototype.name = undefined
- 这是因为你'不要将任何名称
传递给Penguin
构造函数。如果我写了Emperor.prototype = new Penguin(Empy)
那么Emperor.prototype.name
将是Empy
。 -
Emperor.prototype.numLegs = 2
- 显然。
Emperor.prototype.name = undefined
- this is because you're not passing anyname
to thePenguin
constructor. If I'd writtenEmperor.prototype = new Penguin("Empy")
thenEmperor.prototype.name
would be"Empy"
.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:
- 而不是使用
新企鹅()
Penguin 的新实例>并且不传递任何参数,我们使用Object.create(Penguin.prototype)继承
。这也可以防止在实际调用派生构造函数之前对基础构造函数进行不必要的初始化。Penguin
的原型成员 - 而不是编写
this.name = name
in我们再次使用Penguin.call(this,name)
为我们调用基础构造函数。这种模式称为mixin,如果基本构造函数需要在运行时初始化或需要维护自己的状态信息,则非常有用。
- Instead of creating a new instance of
Penguin
usingnew Penguin()
and passing no arguments to it, we inherit the prototype members ofPenguin
usingObject.create(Penguin.prototype)
. This also prevent unnecessary initialization of the base constructor until the derived constructor is actually called. - Instead of writing
this.name = name
in the derived constructor again we call the base constructor usingPenguin.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屋!