Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I merge 2 javascript objects, populating the properties in one if they don't exist in the other?

Tags:

If I have a javascript object/assoc. array defined like this:

function somefunction(options) {

    var defaults = {
        prop1: 'foo',
        prop2: 'bar'
    };

    //Do stuff here

}

and I want to use this as the default values for the function. So when the function gets called I want to populate the options variable with the values in defaults, but only if they don't exist in options.

So lets say that this was called

somefunction({ prop1: 'fish' });

How can I make it so that options gets merged with defaults such that I get this

{
    prop1: 'fish',
    prop2: 'bar'
}
like image 1000
Glenn Slaven Avatar asked May 22 '09 01:05

Glenn Slaven


People also ask

How can I merge properties of two JavaScript objects dynamically?

The two most common ways of doing this are: Using the spread operator ( ... ) Using the Object. assign() method.

How do you combine properties of two objects?

To merge objects into a new one that has all properties of the merged objects, you have two options: Use a spread operator ( ... ) Use the Object. assign() method.

Can we merge two objects in JavaScript?

To merge two objects in JavaScript, you can use the spread ... operator. The spread operator creates a new object with all the properties from the first and second object. If there's two properties with the same name, the property from the second object wins out.

How to merge properties of two JavaScript objects?

To merge 2 JavaScript objects, populating the properties in one if they don’t exist in the other, we can use some object methods. How to Merge Properties of Two JavaScript Objects Dynamically?

How to recursively merge objects in JavaScript?

To recursively merge own and inherited enumerable string keyed properties of source objects to a target object, you can use the Lodash ._merge () method: In this tutorial, you have learned how to merge objects in JavaScript using the spread operator ( ...) and Object.assign () method.

What is shallow merge in JavaScript?

Both the spread operator ( ...) and Object.assign () method perform a shallow merge. It means that if an object has a property that references to another object, the property of the original object and result target object will reference the same object. For example:

What is the best way to merge two objects?

Object.assign (obj1, obj2); may be the preferable way as let merged = {...obj1, ...obj2}; creates a new object and copies the the properties of obj1 and obj2 into it which may be very expensive for large objects. The assign method also modifies obj1 like the behavior expected in the question.


2 Answers

After re-reading the question, I realized you're probably looking for something more like this:

var a = { 'foo': 'bar', 'baz': 'bat' };
var b = { 'foo': 'quux' };
for (var prop in a) {
    if (prop in b) { continue; }
    b[prop] = a[prop];
}
like image 69
TML Avatar answered Sep 24 '22 13:09

TML


You could look at either jQuery's or Prototypes extend functionality.

It looks like this: (taken directly from jQuery)

jQuery.extend = jQuery.fn.extend = function() {
    // copy reference to target object
    var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options;

    // Handle a deep copy situation
    if ( typeof target === "boolean" ) {
        deep = target;
        target = arguments[1] || {};
        // skip the boolean and the target
        i = 2;
    }

    // Handle case when target is a string or something (possible in deep copy)
    if ( typeof target !== "object" && !jQuery.isFunction(target) )
        target = {};

    // extend jQuery itself if only one argument is passed
    if ( length == i ) {
        target = this;
        --i;
    }

    for ( ; i < length; i++ )
        // Only deal with non-null/undefined values
        if ( (options = arguments[ i ]) != null )
            // Extend the base object
            for ( var name in options ) {
                var src = target[ name ], copy = options[ name ];

                // Prevent never-ending loop
                if ( target === copy )
                    continue;

                // Recurse if we're merging object values
                if ( deep && copy && typeof copy === "object" && !copy.nodeType )
                    target[ name ] = jQuery.extend( deep, 
                        // Never move original objects, clone them
                        src || ( copy.length != null ? [ ] : { } )
                    , copy );

                // Don't bring in undefined values
                else if ( copy !== undefined )
                    target[ name ] = copy;

            }

    // Return the modified object
    return target;
};
like image 40
cgp Avatar answered Sep 23 '22 13:09

cgp