javascriptunderscore.js

Recursive/deep extend/assign in Underscore.js?


Is there any way to get Underscore.js extend function:

Copy all of the properties in the source objects over to the destination object, and return the destination object. It's in-order, so the last source will override properties of the same name in previous arguments.

... to work recursively?

Actually, query property in creditOperation is going to completely override the query property defined in baseOperation:

var url = require('url')
  , _ = require('underscore'),
  , baseOperation = {
        host: 'gateway.skebby.it',
        pathname: 'api/send/smseasy/advanced/http.php',
        protocol: 'https',
        query: {
            'username': 'foo',
            'password': 'bar',
        }
    };

var creditOperation = _.extend(baseOperation, {
    query: {
        'method': 'baz'
    }
});

console.log(url.format(creditOperation));

I'd like to obtain this creditOperation:

{
    host: 'gateway.skebby.it',
    pathname: 'api/send/smseasy/advanced/http.php',
    protocol: 'https',
    query: {
        'username': 'foo',
        'password': 'bar',
        'method': 'baz'
    }
}

Solution

  • Underscore has no plans to add a deep extend since it's deemed too complicated to deal with different types of objects. Instead, users are encouraged to implement their own solutions with the support for what they need.

    In your case it's only plain objects, so an implementation is quite straightforward:

    _.deepObjectExtend = function(target, source) {
        for (var prop in source)
            if (prop in target)
                _.deepObjectExtend(target[prop], source[prop]);
            else
                target[prop] = source[prop];
        return target;
    }