If I have a javascript object/assoc. array defined like this:
function somefunction(options) {
var defaults = {
prop1: \'foo\',
prop2: \'bar
Using Google Closure Library it can be done like that:
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.
}
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];
}
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;
};
<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>
I'm a PrototypeJS holdout. Us Java-types prefer PrototypeJS's OO design over jQuery. Here's how you merge two Object/Hash/Maps with Proto:
$H(obj1).merge(obj2).toObject()
The input obj1 and obj2 are unaffected. obj2 map entries have precedence (i.e. obj1 and obj2 both have same key, the value for that key in obj2 will override).