Comment fusionner 2 objets javascript, peupler les propriétés en une si elles n'existent pas dans l'autre?

Si j'ai un objet javascript / assoc. Tableau défini comme ceci:

function somefunction(options) { var defaults = { prop1: 'foo', prop2: 'bar' }; //Do stuff here } 

Et je veux utiliser cette valeur comme valeur par défaut pour la fonction. Donc, lorsque la fonction s'appelle, je veux remplir la variable d' options avec les valeurs par defaults , mais seulement si elles n'existent pas dans les options .

Donc disons que cela s'appelait

 somefunction({ prop1: 'fish' }); 

Comment puis-je le faire pour que les options soient fusionnées avec les defaults par defaults sorte que je reçois ce

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

Vous pouvez regarder les fonctionnalités de jQuery's ou Prototypes.

Cela ressemble à ceci: (pris directement à partir de 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; }; 

Après avoir lu la question, je me suis rendu compte que vous cherchez probablement quelque chose comme ceci:

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

Je suis un ProTotypeJS holdout. Les types Java préfèrent la conception OO PrototypeJS sur jQuery. Voici comment fusionnez deux objets / Hash / Maps avec Proto:

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

L'entrée obj1 et obj2 ne sont pas affectées. Les entrées de la carte obj2 ont la priorité (c.-à-d. Obj1 et obj2 ont toutes deux la même clé, la valeur de cette clé dans obj2 sera remplacée).

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

À l'aide de Google Closure Library, cela se fait comme ça:

 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. }