Skip to content

Instantly share code, notes, and snippets.

@joseanpg
Created August 15, 2012 21:55
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save joseanpg/3364036 to your computer and use it in GitHub Desktop.
Save joseanpg/3364036 to your computer and use it in GitHub Desktop.
Extend and Merge (don't overwrite properties that reference objects)
(function(carrier){
var hasOwn = Object.prototype.hasOwnProperty;
var slice = Array.prototype.slice;
function extend(obj,src){
for (var p in src){
if (hasOwn.call(src,p)) {
if (p in obj && typeof obj[p] === 'object' && obj[p]) {
extend(obj[p],src[p]);
}
else {
obj[p] = src[p];
}
}
}
}
function merge(){
var result = {};
var args = slice.call(arguments,0);
for (var i=0, len=args.length;i<len;i++){
extend(result,args[i]);
}
return result;
}
carrier.extend = extend;
carrier.merge = merge;
})(this);
/*
var a = {};
var b = {a:'Hello', b:{}};
var c = {a:'Bye', b:{f:{d:2}}, c:1};
var r = merge(a, b, c);
alert(JSON.stringify(r,null,0)); //{"a":"Bye","b":{"f":{"d":2}},"c":1}
*/
@FGRibreau
Copy link

var a = {};
var b = {a:'Hello', b:{}};
var c = {a:'Bye', b:{f:{d:2}}, c:1};

var r = myextend(a, b, c);

// don't modify arguments
deepEqual(a, {});
deepEqual(b, {a:'Hello', b:{}});
deepEqual(c, {a:'Bye', b:{f:{d:2}}, c:1});

// test the result
deepEqual(r, {"a":"Bye","b":{"f":{"d":2}},"c":1});

@FGRibreau
Copy link

You're right, that was fun :D

function myextend(/* args */){
var o = {}
, args = Array.prototype.slice.call(arguments)
,  obj = args.shift()
,  src = args.shift();

  for (var p in src){
    if (src.hasOwnProperty(p)){
      if (p in obj && typeof obj[p] === 'object' && obj[p] !== null) {
        o[p] = myextend(obj[p],src[p]);
      }
      else {
        o[p] = src[p];
      }
    }
  }

return args.length > 0 ? myextend.apply(null, [o].concat(args)) : o;
}

@WebReflection
Copy link

hasOwn.call(obj,p) && p in obj ... don't you think the second one is quite redundant? ... typeof obj[p] === 'object' && obj[p] !== null ... could be typeof obj[p] === 'object' && obj[p] ;-)

@joseanpg
Copy link
Author

You are right :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment