Last Updated: August 01, 2018
·
6.379K
· 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 ·

Have a fresh tip? Share with Coderwall community!

Post
Post a tip
Did you know?

JavaScript on a page runs with the privileges of that origin. One altered library, tag manager, or snippet can read inputs, change what people see, and call your APIs as the user.

Security insights from Cside