Last Updated: August 01, 2018
·
6.154K
· tencircles

Object.extend Black Magic

Just an interesting inheritance mixin I use from time to time. Haven't seen it around on the web,
thought you might enjoy it.

function extend () {
 return [].reduce.call(arguments, Object.create, this);
}

Create yourself a prototype and add in the ye olde extend magic.
Let's just use the classic example of person/say name we all know and love.

var person = {
 sayName: function () {
 console.log("Hello, my name is " + this.name);
 return this;
 },
 name: "John Doe",
 extend: extend
};

Now let's create another "prototype", but not too specific. Just add in some extra functionality.
Note this is formatting using Object.create's propertiesObject argument.

var ninja = {
 hide: {
 value: function () {
 this.hidden = true;
 return this;
 }
 }
};

Maybe another for good measure? Be sure to note here that these don't inherit from person, it's just some behavior or data we might want to add to a person.

var wizard = {
 fireball: {
 value: function () {
 console.log("Pew Pew!");
 return this;
 }
 }
};

And now: a god-damned ninja-wizard.

var ninjaWizard = person.extend(ninja, wizard, {
 name: {
 value: "Ninja Wizard"
 },
 wtf: {
 value: function () {
 console.log("RWAWRRRGGGGG!");
 return this;
 }
 }
});

ninjaWizard.sayName().wtf().fireball().hide();

Maybe create a son of Ninja Wizard?

var shaggar = ninjaWizard.extend({
 name: {
 value: "Shaggar, Son of Dolff"
 },
 feedToGoats: {
 value: function () {
 if (this.hasCutoffManhood) {
 //Do things
 } 
 }
 }
});
shaggar.sayName().feedToGoats();

The above works with as many prototypes as you'd like to throw at it. If you want to do a little
formatting to avoid the verbosity of Object.create, go for it. I personally don't mind it.

EDIT: For those of you interested, I've created a very small library with this functionality: metatype.js.

7 Responses
Add your response

Tags: "wizards", "ninjas". Niiiice.

over 1 year ago ·

This is pretty sick, nice trick

over 1 year ago ·

hi chris, that looks great. does it have any disatvangtes compared to the standard extend method (like underscore's)?

over 1 year ago ·

Awesome!!!

over 1 year ago ·

This should be in standard.

over 1 year ago ·

Hey @oronm, this is a very different type of functionality than underscore's extend. The extend in underscore simply copies properties from one object to another. This is creating a new object in which the prototype chain extends from the object on which the method was called, includes each argument passed, and ends with the new object.

over 1 year ago ·

"a god-damned ninja-wizard" code that is :)
Awesome tip!

over 1 year ago ·