2009-05-22 25 views
20

如果我有一個javascript對象/ assoc。 array這樣定義:如何合併2個JavaScript對象,如果它們不存在於另一箇中,則將其中的屬性填充到一個對象中?

function somefunction(options) { 

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

    //Do stuff here 

} 

我想用這個作爲函數的默認值。所以當函數被調用時,我想用defaults中的值填充options變量,但前提是它們不存在於options中。

因此,可以說,這種被稱爲

somefunction({ prop1: 'fish' }); 

我怎樣才能讓這個options獲取與defaults這樣,我得到合併這

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

回答

12

你可以看看jQuery的或原型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; 
}; 
+0

似乎是一個可怕的很多工作來執行一些深拷貝魔術 - 是否有必要? – TML 2009-05-22 01:52:25

+0

這是一個很好的問題,深拷貝的東西可能是矯枉過正的。 – cgp 2009-05-22 02:03:16

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]; 
} 
+3

非常感謝,這應該是公認的答案:) – Phradion 2012-10-16 05:11:03

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> 
2

我是PrototypeJS抵抗。我們Java類型更喜歡PrototypeJS的面向jQuery的OO設計。以下是將兩個Object/Hash/Maps與Proto合併的示例:

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

輸入obj1和obj2不受影響。 obj2映射條目具有優先級(即,obj1和obj2都具有相同的密鑰,obj2中該密鑰的值將被覆蓋)。

1

使用谷歌關閉圖書館可以做到這樣的:

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. 
} 
相關問題