DZone
Web Dev Zone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
  • Refcardz
  • Trend Reports
  • Webinars
  • Zones
  • |
    • Agile
    • AI
    • Big Data
    • Cloud
    • Database
    • DevOps
    • Integration
    • IoT
    • Java
    • Microservices
    • Open Source
    • Performance
    • Security
    • Web Dev
DZone > Web Dev Zone > Multiple object extend pattern in JavaScript

Multiple object extend pattern in JavaScript

Vladimir Carrer user avatar by
Vladimir Carrer
·
Jun. 22, 11 · Web Dev Zone · Interview
Like (0)
Save
Tweet
2.73K Views

Join the DZone community and get the full member experience.

Join For Free

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

Object (computer science) JavaScript

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • How to Utilize Python Machine Learning Models
  • How to Test JavaScript Code in a Browser
  • The End of the Beginning for Apache Cassandra
  • Why I'm Choosing Pulumi Over Terraform

Comments

Web Dev Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • MVB Program
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends:

DZone.com is powered by 

AnswerHub logo