JavaScript中的对象继承 [英] Object Inheritance in JavaScript

查看:97
本文介绍了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 构造函数将直接继承自 {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屋!

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