Object Inheritance in JavaScript

前端 未结 2 1204
情话喂你
情话喂你 2020-12-16 08:00

My question is regarding a child object maintaining the prototype chain of its parent object.

In John Resig\'s Advanced Javascript slides (http://ejohn.org/apps/lear

2条回答
  •  春和景丽
    2020-12-16 09:01

    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 };
    

    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    |
    +------------------+
    

    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     |
    +-------------------+
    

    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.

    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    |
    +------------------+
    

    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.

提交回复
热议问题