如何合并2个javascript对象,如果它们不存在于另一个中,则将属性填充到一个中?

时间:2009-05-22 01:32:11

标签: javascript arrays merge

如果我有一个javascript对象/ assoc。数组定义如下:

function somefunction(options) {

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

    //Do stuff here

}

我想用它作为函数的默认值。因此,当函数被调用时,我想使用options中的值填充defaults变量,但前提是它们options中不存在。

所以我要说这叫做

somefunction({ prop1: 'fish' });

我如何才能使optionsdefaults合并,以便我得到这个

{
    prop1: 'fish',
    prop2: 'bar'
}

5 个答案:

答案 0 :(得分:42)

重新阅读问题之后,我意识到你可能正在寻找更像这样的东西:

var a = { 'foo': 'bar', 'baz': 'bat' };
var b = { 'foo': 'quux' };
for (var prop in a) {
    if (prop in b) { continue; }
    b[prop] = a[prop];
}

答案 1 :(得分:12)

您可以查看jQuery或Prototypes extend功能。

它看起来像这样:(直接取自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;
};

答案 2 :(得分:2)

我是PrototypeJS坚持。我们Java类型更喜欢PrototypeJS的OO设计而不是jQuery。以下是将两个Object / Hash / Maps与Proto合并的方法:

$H(obj1).merge(obj2).toObject()

输入obj1和obj2不受影响。 obj2映射条目具有优先权(即obj1和obj2都具有相同的键,obj2中该键的值将覆盖)。

答案 3 :(得分:1)

<html>
<head> 
<title>Testing</title>

<script type="text/JavaScript">
// The method is simpler than its demonstration:

function merge(obj1, obj2, force){
    for(var p in obj2){
        if(force || obj1[p]=== undefined) obj1[p]= obj2[p];
    }
    return obj1;
}

// demo:
var merge_demo= function(){
    // set up a to string method, just for the demo
    var restring= function(){
        var s= [];
        for(var p in this){
            s[s.length]= p+': '+this[p];
        }
        return '{ '+s.join(', ')+' }';
    }
    // define two objects
    var O1={
        a: 1, b: 2, c: 3
    }
    var O2={
        a: 10, b: 11, d: 4
    }
    // Begin demo, write the object contents to a string:
    var str= 'Object1='+restring.call(O1)+'\nObject2='+restring.call(O2)+'\n\n';

    //merge the two objects without overwriting values: 
    merge(O1, O2);

    // Update object contents in string:
    str+= 'merge(Object1,Object2)='+restring.call(O1)+'\n\n';

    //merge and replace existing values:
    merge(O1, O2, true);

    // Update and return string: 
    str+= 'merge(Object1,Object2,true)='+restring.call(O1);
    return str;
}
alert(merge_demo());
</script>
</head>

<body>
</body>
</html>

答案 4 :(得分:1)

使用Google Closure库可以这样做:

goog.require('goog.object');
function somefunction(options) {
  var defaults = {
    prop1: 'foo',
    prop2: 'bar'
  };
  goog.object.extend(defaults, options);
  // if the property is defined in options it will overwrite value.
}