Where developers come to connect, share, build and be inspired.

3

Object.extend Black Magic

5482 views


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.

Comments

  • 0fnsi63t_normal

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

  • 0_goniworhrdizozyquf6pwgf5-inze1mqumcywgyqda8xvbm6m2qfljhvp5qidq7eidnjkvahsbu_

    This is pretty sick, nice trick

  • 55e62171d8f1b780c9439899d36cc6dc_normal

    Awesome!!!

  • Me

    This should be in standard.

  • Cf7a5a69a6ea64cb0b8a6eac32cad791

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

  • 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.

  • 4693d7cfa88635d430c0de9a92f8dd84

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

Add a comment