JavaScript中的对象继承

斯米先生

我的问题是关于子对象维护其父对象的原型链。

在John Resig的Advanced Javascript幻灯片(http://ejohn.org/apps/learn/#76)中,他写道,为了维护子对象的原型链,必须实例化一个新的父对象。

但是,通过几次快速测试,我注意到仅通过将子对象原型设置为与父对象原型相等就可以维护原型链。

任何澄清将不胜感激!

原始码

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.prototypePerson.prototype然后,他立即将其重置为{ dance: Person.prototype.dance }

// Achieve similar, but non-inheritable, results
Ninja.prototype = Person.prototype;
Ninja.prototype = { dance: Person.prototype.dance };

结果是,Ninja构造函数创建的任何对象都将直接继承,{ dance: Person.prototype.dance }而不是的实例Person.prototype因此(new Ninja) instanceof Person将返回false。在这种情况下,原型链为:

        null
         ^
         |
         | [[prototype]]
         |
+------------------+
| Object.prototype |
+------------------+
         ^
         |
         | [[prototype]]
         |
+------------------+
|  Ninja.prototype |
+------------------+
         ^
         |
         | [[prototype]]
         |
+------------------+
|     new Ninja    |
+------------------+

在修改后的版本中,您删除了第二个分配,以Ninja.prototype有效地设置Ninja.prototypePerson.prototype因此,原型链为:

         null
          ^
          |
          | [[prototype]]
          |
+-------------------+
|  Object.prototype |
+-------------------+
          ^
          |
          | [[prototype]]
          |
+-------------------+
| Ninja.prototype / |
| Person.prototype  |
+-------------------+
          ^
          |
          | [[prototype]]
          |
+-------------------+
|     new Ninja     |
+-------------------+

请注意,since两者都Ninja.prototype相同,并且会返回这是因为运算符取决于构造函数的Person.prototype(new Ninja) intanceof Ninja(new Ninja) instanceof Persontrueinstanceofprototype

但是,要在JavaScript中实现继承的正确方法是将设置Ninja.prototypeObject.create(Person.prototype)(或以旧的方式设置为new Person),在这种情况下,原型链将为:

        null
         ^
         |
         | [[prototype]]
         |
+------------------+
| Object.prototype |
+------------------+
         ^
         |
         | [[prototype]]
         |
+------------------+
| Person.prototype |
+------------------+
         ^
         |
         | [[prototype]]
         |
+------------------+
|  Ninja.prototype |
+------------------+
         ^
         |
         | [[prototype]]
         |
+------------------+
|     new Ninja    |
+------------------+

注意:切记,在JavaScript中,对象是从其他对象继承的。它们从不继承构造函数。如果您想了解JavaScript中真正的原型继承,请阅读我的博客文章,了解原型惯用性为何如此重要

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章