Javascript: What are multi-level prototype hierarchies and why we should avoid it

2k views Asked by At

In the Google Javascript Coding Guidelines, it said that we should not use Multi-level prototype hierarchies because "These hierarchies are much harder to get right than they first appear!". Actually I didn't get what it means. Where can I find a good example to explain its usage and illustrate its bad effect?

3

There are 3 answers

2
Pavel Podlipensky On

This is because of prototype chain resolution problem. When you have something like foo.bar it doesn't mean that bar property belongs directly to foo object, so it start to search for bar in prototype chain of foo. If chain is long then property resolution could be relatively long operation.

0
Šime Vidas On

This is an example of two-level inheritance:

// 1. level constructor
var Dog = function ( name ) {
    this.name = name;
};

Dog.prototype.bark = function () { /* ... */ };

// 2. level constructor
var TrainedDog = function ( name, level ) {
    Dog.apply( this, arguments ); // calling the super constructor
    this.level = level;
};

// set up two-level inheritance
TrainedDog.prototype = Object.create( Dog.prototype );
TrainedDog.prototype.constructor = TrainedDog;

TrainedDog.prototype.rollOver = function () { /* ... */ };

// instances
var dog1 = new Dog( 'Rex' );
var dog2 = new TrainedDog( 'Rock', 3 );

Here, dog1 inherits the bark method from the Dog prototype, and dog2 inherits both that method (from the Dog prototype) and the rollOver method from the TrainedDog prototype.

0
Raynos On

I believe the article is referring to not manually setting up the prototype chains but using a library, like goog.inherits or util.inherits

manually you would have to do

var Child = function Child() { ... };

Child.prototype = Object.create(Parent.prototype);
Child.prototype.constructor = Child;
// for some common value of extend
extend(Child.prototype, {
  ...
});

This can be simplified to

var Child = function Child() { ... };

goog.inherits(Child, Parent);
extend(Child.prototype, {
  ...
});

Note here goog.inherits also deals with Object.create emulation in legacy browsers.