Archive for the ‘underscore.js’ Category

Underscore.js extend vs. jQuery extend

April 2, 2013

Or more succintly: _.extend vs. $.extend.

They both try the same thing and that is copy the keys from a series of objects into the first object. They extend the first object with the properties in the other objects, like this:

    var a = { k0 : 0 },
        b = { k1 : 1, k2 : 2 };
        c = { k3 : 3, k4 : 4 };
    _.extend(a, b, c);

After the extend, a will be:

       k0 : 0,
       k1 : 1,
       k2 : 2,
       k3 : 3,
       k4 : 4

It can be used to extend objects, and it commonly used for “inheritance” : extending one object’s prototype with the properties and functions of another object. Here’s an example from backbone.js, which extends the Model’s prototype:

   _.extend(Model.prototype, Events, { 
             //more implementation here...

One major difference between underscore.js extend and jquery extend is in the way they deal with sub-objects or nested objects. Jquery does a deep copy of sub-objects, while underscore.js does a shallow copy. You need to keep this in mind as problems caused by shallow copies can be hard to troubleshoot.

Have a look at this code:

    var a = {}, b = {},
        c = { k1 : 1,
              kobj : { k2 : 2 }
    _.extend(a, c);
    _.extend(b, c);
    a.kobj.k2 = 10;
    console.log("a.kobj.k2:", a.kobj.k2);
    console.log("c.kobj.k2:", c.kobj.k2);

Because _.extend does a shallow copy, both a.kobj and c.kobj point to the same object. So changing one, affects the other. The code above shows 10 for both a.kobj.k2 and c.kobj.k2.

Replace _.extend with $.extend and the code does a deep copy and the code above displays a.kobj.k2: 10 and c.kobj.k2: 2.