Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Multiple object extend pattern in JavaScript

DZone's Guide to

Multiple object extend pattern in JavaScript

· Web Dev Zone
Free Resource

Start coding today to experience the powerful engine that drives data application’s development, brought to you in partnership with Qlik.

I was doing some research about JavaScript Inheritance patterns realizing there are many different approaches and divided opinions which pattern or method is better. There is no widely accepted bulletproof pattern that will cover every possible scenario, probably because It all depends what you trying to achieve.

I needed a pattern that can accept and extend multiple objects. Usually is very common to see one object that extends another object extend(object1, object2) but I needed pattern that accepts multiple objects like extend(object1, object2, object3). So I decided to make one.

I used Douglas Crockford - Prototypal Inheritance logic, temporally function -> Object.prototype -> new object plus looping inside every object to copy all the methods.

The first pattern accepts only objects:

function extend() {

    var i = arguments.length;

    function F() {}

    while (i--) {

        for (var m in arguments[i]) {
            F.prototype[m] = arguments[i][m];

        }

    }

    return new F();

}

I also made the second pattern in case you want to use function for storing methods.It is highly unlikely that you will use the function just for storing methods, but anyway here is the pattern.

function extendAll() {

    var i = arguments.length;

    function F() {}

    function N() {}

    while (i--) {

        for (var method in arguments[i]) {
            F.prototype[method] = arguments[i][method];

        }

        if (typeof arguments[i] !== "object") {
            N.prototype = new arguments[i]();
            for (var m in N.prototype) {
                F.prototype[m] = N.prototype[m];

            }
        }

    }

    return new F();

}

From the preliminary tests, this pattern should work even in IE 5.5.

Sometimes it can be handy to merge objects or to divide one object in smaller units to increase modularity. Many modern JS Frameworks have one object that holds everything, dividing that object into smaller logical components(objects) can be helpful.

Two months ago I made picoCSS small JS framework for making webkit apps. I will rewrite the picoCSS to demonstrate the functionality of this pattern. Many JS framework have modules like: selector engine, css, animation, other DOM methods, ajax, events … The intention behind this pattern is to merge just the objects(modules) that we need.

Here is picoCSS original and viewed with Object Auto Documentation. Everything is stored inside the object p. The goal is to brake picoCSS several objects like selector, events, animation …

And picoCSS after:

var selector = {

    select: function (selector) {
        this.value = Array.prototype.slice.call(document.querySelectorAll(selector));
        return this;
    }
};

var loop = {
    each: [].forEach,
    map: [].map
};

var css = {
    css: function (v) {
        this.value = this.each.call(this.value, function (i) {
            i.style.cssText = v;
        });
        return this;
    },

    att: function (a, v) {
        this.value = this.each.call(this.value, function (i) {
            i.setAttribute(a, v);
        });
        return this;
    }
};

var animation = {
    animate: function (time, scale, rotate, rotateX, rotateY, translateX, translateY, skewX, skewY) {
        this.value = [].forEach.call(this.value, function (i) {
            i.style.cssText = '-webkit-transition: all ' + time + 's ease-in-out; -webkit-transform: scale(' + scale + ') rotate(' + rotate + 'deg) rotateX(' + rotateX + 'deg) rotateY(' + rotateY + 'deg) translate(' + translateX + 'px, ' + translateY + 'px) skew(' + skewX + 'deg, ' + skewY + 'deg)';
        });
        return this;
    }
};

var events = {
    on: function (type, fn) {
        this.value = this.each.call(this.value, function (i) {
            i.addEventListener(type, fn, false);
        });
        return this;
    }

};

Now we can rebuild picoCSS like this: var p = extend(selector, css, loop, events);

The working demo.

In this way we loaded just the objects and methods that we need. This particular case dividing the object has little sense because we have super small library. But in other bigger projects dividing the logic can be very useful not just for increasing modularity but also for decreasing the memory consummation. We can even make different files for every object and load only the files that we use. Naturally we should be careful not to make to many HTTP requests.

Here are some I tests I made

Your comments and suggestions about improving this pattern are welcomed.

From http://www.vcarrer.com/2011/06/multiple-object-extend-pattern-in.html

Create data driven applications in Qlik’s free and easy to use coding environment, brought to you in partnership with Qlik.

Topics:

Opinions expressed by DZone contributors are their own.

THE DZONE NEWSLETTER

Dev Resources & Solutions Straight to Your Inbox

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

X

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}