6

I'm reading about the mixin pattern in javascript and I encountered this piece of code that I don't understand:

SuperHero.prototype = Object.create( Person.prototype );

There is actually a typo in the original code (the uppercase H). If I downcase it it works. However, if I actually delete the line everything seems to work the same.

Here is the full code:

var Person =  function( firstName , lastName ){
  this.firstName = firstName;
  this.lastName =  lastName;
  this.gender = "male";
};

// a new instance of Person can then easily be created as follows:
var clark = new Person( "Clark" , "Kent" );

// Define a subclass constructor for for "Superhero":
var Superhero = function( firstName, lastName , powers ){

    // Invoke the superclass constructor on the new object
    // then use .call() to invoke the constructor as a method of
    // the object to be initialized.

    Person.call( this, firstName, lastName );

    // Finally, store their powers, a new array of traits not found in a normal "Person"
    this.powers = powers;
};

SuperHero.prototype = Object.create( Person.prototype );
var superman = new Superhero( "Clark" ,"Kent" , ["flight","heat-vision"] );
console.log( superman ); 

// Outputs Person attributes as well as powers

What does SuperHero.prototype = Object.create( Person.prototype ); do?

1

3 Answers 3

4

It creates a new object that inherits from the Person constructor's prototype object.

It would be just like if you did this.

SuperHero.prototype = new Person();

Except that it creates the Person instance without actually invoking the code in the Person constructor.

This object is used as the prototype object of the SuperHero constructor, so that when you create a SuperHero instance, it will inherit all the prototyped properties of Person, as well as any prototyped properties added directly to the SuperHero prototype object.

Sign up to request clarification or add additional context in comments.

12 Comments

Ahhh, so if there's Person.prototype.die = function(){...} I can then do superhero.die() ?
@Duopixel: Exactly. :) The prototype chain will search in the order of object -> SuperHero.prototype -> Person.prototype -> Object.prototype -> null;
@graystateiscoming +1 btw - quick question: "without actually invoking the code in the Person constructor". This part is throwing me off, what do you mean by that?
@mcpDESIGNS: In ECMAScript 3, you could only create a custom object by invoking a constructor function. So to create a Person, you would need to invoke the Person function using new, as in var p = new Person(). But in ECMAScript 5, we get Object.create, which lets us create an object that has the exact same prototype chain as an object made using new, except that we didn't need to actually call the Person function. This is useful if we want a plain Person object without the side effects of the constructor function.
@mcpDESIGNS: Use it today! :) jsfiddle.net/KAtmJ This is a shim that lets you do nearly the same. It doesn't support the second argument to Object.create, and doesn't let you use null as the prototype object, but it does let you create objects that inherit from a specified prototype. Enjoy! :)
|
1

It does exactly as the docs state:

Creates a new object with the specified prototype object and properties.

The proto in this case is Person:

The parameter states the following:

The object which should be the prototype of the newly-created object.

Your code Object.create( Person.prototype ); returns an object that copies the properties (in this case the firstName, lastName, and gender) of a person and assigns them to a SuperHero.

Note the similarities between a Person and a SuperHero they both contain a firstName and a lastName. Note also the differences, the Person contains a gender property while your SuperHero contains a powers property.

4 Comments

Object.create doesn't copy any properties. The object created using Object.create(Person.prototype) will not have the firstName, lastName, and gender properties that are assigned in the Person constructor.
But it doesn't really even obtain them... that is unless they are manually copied to the object, which in this case, it is inside the SuperHero constructor with Person.call(this, firstName, lastName); where the Person function will directly assign them. But it's not coming from the Object.create(Person.prototype), because those properties are not prototyped.
@graystateiscoming they inherit those properties.
Nope, the properties are not inherited. They are assigned directly to the object because of the Person.call(this...) invocation.
1
SuperHero.prototype = Object.create( Person.prototype );

This is basically letting SuperHero inherit all of the properties/prototypes of Person. It is almost the same as using new, but in the new ECMAScript 5 *Object.create()` way. This could also be written like so, if it helps understand it any more.

SuperHero.prototype = new Person();

I don't like linking the prototypes specifically, because it means the two prototypes are intertwined, and I prefer to have one be the SubClass, one the SuperClass.

A good way to see them yourself is do something like this. Here you can really see the inheritance that SuperHero is getting from Person. Notice it has all of the properties (first/last/etc), and it's additional Powers.

jsFiddle demo

var person = new Person();
SuperHero.prototype = person; // inheritance here
// the Object.create way is ECMAScript 5 (which not all browsers support yet sadly)

var superman = new SuperHero( "Clark" ,"Kent" , ["flight","heat-vision"] );
console.log( person );
console.log( superman ); ​

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.