gyriuq

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.

Sign in or sign up to add your response.

7 Responses

13708
0fnsi63t normal

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

over 1 year ago ·
13724
0 goniworhrdizozyquf6pwgf5 inze1mqumcywgyqda8xvbm6m2qfljhvp5qidq7eidnjkvahsbu

This is pretty sick, nice trick

over 1 year ago ·
13775
Cf7a5a69a6ea64cb0b8a6eac32cad791

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

over 1 year ago ·
13776
55e62171d8f1b780c9439899d36cc6dc normal

Awesome!!!

over 1 year ago ·
13783
Me

This should be in standard.

over 1 year ago ·
13786
7bb511a89868311f7ce08747f7105913

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 ·
13832
4693d7cfa88635d430c0de9a92f8dd84

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

over 1 year ago ·