Basic Inheritance with Object.create
Originally published in the A Drip of JavaScript newsletter.
A few issues back we looked at how to implement basic inheritance with constructors. In this issue, we'll look at how to do the same with the newer Object.create
.
When using constructors for inheritance, we attach properties to the constructor's prototype
property like so:
Here's a little refresher:
function SuperHuman (name, superPower) {
this.name = name;
this.superPower = superPower;
}
SuperHuman.prototype.usePower = function () {
console.log(this.superPower + "!");
};
var banshee = new SuperHuman("Silver Banshee", "sonic wail");
// Outputs: "sonic wail!"
banshee.usePower();
The SuperHuman
constructor contains our initialization logic, while SuperHuman.prototype
contains the methods that are shared across all SuperHuman
instances.
If we were to implement the same basic logic using Object.create
, it would look a bit different:
var superHuman = {
usePower: function () {
console.log(this.superPower + "!");
}
};
var banshee = Object.create(superHuman, {
name: { value: "Silver Banshee" },
superPower: { value: "sonic wail" }
});
// Outputs: "sonic wail!"
banshee.usePower();
In this case we first define the prototype object superHuman
, and then we use Object.create
to make a new object which inherits from superHuman
. That second argument might look a little strange to you, but it's just a simple property descriptor object, like we use with Object.defineProperty
to fine-tune an object's properties.
Now, what if we want to create a new type which inherits from superHuman
while adding its own functionality? What would that look like?
var superHero = Object.create(superHuman, {
allegiance: { value: "Good" },
saveTheDay: {
value: function () {
console.log(this.name + " saved the day!");
}
}
});
var marvel = Object.create(superHero, {
name: { value: "Captain Marvel" },
superPower: { value: "magic" }
});
// Outputs: "Captain Marvel saved the day!"
marvel.saveTheDay();
So far so good. But does Captain Marvel have access to the superHuman
prototype methods?
// Outputs: "magic!"
marvel.usePower();
Yes, she does!
Using Object.create
makes setting up inheritance chains simple because any object can be used as a prototype. However, inheritance managed by Object.create
can't be detected by instanceof
. Instead you'll need to use the isPrototypeOf
method, like so:
// Outputs: true
console.log(superHero.isPrototypeOf(marvel));
// Outputs: true
console.log(superHuman.isPrototypeOf(marvel));
Because both superHero
and superHuman
are part of marvel
's prototype chain, their isPrototypeOf
calls each return true.
As with other JavaScript features we've reviewed, Object.create
is a feature of ECMAScript 5 and is not available in older browsers like IE8.
That's our brief introduction to using Object.create
. Thanks for reading!
Joshua Clanton