JavaScript中的对象继承 [英] Object Inheritance in JavaScript
问题描述
我的问题是关于维护其父对象的原型链的子对象。
My question is regarding a child object maintaining the prototype chain of its parent object.
在John Resig的高级Javascript幻灯片中( http://ejohn.org/apps/learn/#76 )他写道,为了维护子对象的原型链你必须实例化一个新的父对象。
In John Resig's Advanced Javascript slides (http://ejohn.org/apps/learn/#76) he writes that in order to maintain the prototype chain of a child object you must instantiate a new parent object.
然而,通过几次快速测试,我注意到只需将子对象原型设置为等于父对象原型即可维护原型链。 。
However through a couple quick tests I noticed that the prototype chain is maintained by just setting the child object prototype equal to the parent object prototype.
非常感谢任何澄清!
原始代码
function Person(){}
Person.prototype.dance = function(){};
function Ninja(){}
// Achieve similar, but non-inheritable, results
Ninja.prototype = Person.prototype;
Ninja.prototype = { dance: Person.prototype.dance };
assert( (new Ninja()) instanceof Person, "Will fail with bad prototype chain." );
// Only this maintains the prototype chain
Ninja.prototype = new Person();
var ninja = new Ninja();
assert( ninja instanceof Ninja, "ninja receives functionality from the Ninja prototype" );
assert( ninja instanceof Person, "... and the Person prototype" );
assert( ninja instanceof Object, "... and the Object prototype" );
我的修改版
function Person(){}
Person.prototype.dance = function(){console.log("Dance")};
function Ninja(){}
// Achieve similar, but non-inheritable, results
Ninja.prototype = Person.prototype;
assert( (new Ninja()) instanceof Person, "Will fail with bad prototype chain." );
var ninja = new Ninja();
assert( ninja instanceof Ninja, "ninja receives functionality from the Ninja prototype" );
assert( ninja instanceof Person, "... and the Person prototype" );
assert( ninja instanceof Object, "... and the Object prototype" );
ninja.dance();
推荐答案
在John Resig提供的代码中,他首先设置 Ninja.prototype
到 Person.prototype
。然后他立即将其重置为 {dance:Person.prototype.dance}
:
In the code John Resig provided he first sets Ninja.prototype
to Person.prototype
. Then he immediately resets it to { dance: Person.prototype.dance }
:
// Achieve similar, but non-inheritable, results
Ninja.prototype = Person.prototype;
Ninja.prototype = { dance: Person.prototype.dance };
结果是 Ninja $ c $创建的任何对象c>构造函数将直接继承自
{dance:Person.prototype.dance}
,这不是 Person.prototype
。因此(新忍者)instanceof Person
将返回false。在这种情况下,原型链是:
The result is that any object created by the Ninja
constructor will directly inherit from { dance: Person.prototype.dance }
which is not an instance of Person.prototype
. Hence (new Ninja) instanceof Person
will return false. In this case the prototype chain is:
null
^
|
| [[prototype]]
|
+------------------+
| Object.prototype |
+------------------+
^
|
| [[prototype]]
|
+------------------+
| Ninja.prototype |
+------------------+
^
|
| [[prototype]]
|
+------------------+
| new Ninja |
+------------------+
在修改后的版本中,您将第二个作业删除为 Ninja.prototype
,有效地将 Ninja.prototype
设置为 Person.prototype的
。因此原型链是:
In the modified version you remove the second assignment to Ninja.prototype
, effectively setting Ninja.prototype
to Person.prototype
. Hence the prototype chain is:
null
^
|
| [[prototype]]
|
+-------------------+
| Object.prototype |
+-------------------+
^
|
| [[prototype]]
|
+-------------------+
| Ninja.prototype / |
| Person.prototype |
+-------------------+
^
|
| [[prototype]]
|
+-------------------+
| new Ninja |
+-------------------+
请注意,因为 Ninja.prototype
与 Person.prototype
相同 (新忍者)恩蒂娅
和(新忍者)实例人
将返回 true
。这是因为 instanceof
运算符取决于构造函数的原型
。
Notice that since Ninja.prototype
is the same as Person.prototype
both (new Ninja) intanceof Ninja
and (new Ninja) instanceof Person
will return true
. This is because the instanceof
operator depends on the prototype
of a constructor.
然而,正确的方法可以实现继承在JavaScript中将 Ninja.prototype
设置为 Object.create(Person.prototype)
(或在旧学校)到新人
的方式,在这种情况下,原型链将是:
However the right way to do achieve inheritance in JavaScript would be to set Ninja.prototype
to Object.create(Person.prototype)
(or in the old school way to new Person
), in which case the prototype chain would be:
null
^
|
| [[prototype]]
|
+------------------+
| Object.prototype |
+------------------+
^
|
| [[prototype]]
|
+------------------+
| Person.prototype |
+------------------+
^
|
| [[prototype]]
|
+------------------+
| Ninja.prototype |
+------------------+
^
|
| [[prototype]]
|
+------------------+
| new Ninja |
+------------------+
注意:始终记住,JavaScript对象继承自其他对象。它们从不继承构造函数。如果你想在JavaScript中学习真正的原型继承,请阅读我的博客文章为什么原型的重要性很重要。
Note: Always remember that in JavaScript objects inherit from other objects. They never inherit from constructor functions. If you wish to learn about true prototypal inheritance in JavaScript then read my blog post on why prototypal inhritance matters.
这篇关于JavaScript中的对象继承的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!