I need to merge two objects in a code path that is going to be heavily used.  The code works, but I am concerned it is not optimized enough for speed and I am looking for any suggestions to improve/replace what I have come up with.  I originally started working off an example at the end of this issue: https://stackoverflow.com/questions/171251/how-can-i-merge-properties-of-two-javascript-objects-dynamically.  That solution works well for simple objects.   However, my needs have a twist to it which is where the performance concerns come in.  I need to be able to support arrays such that an array of simple values will look for values in the new object and add those to the end of the existing object and an array of objects will either merge objects (based off existence of an id property) or push new objects (objects whose id property does not exist) to the end of the existing array.I do not need functions/method cloning and I don't care about hasOwnProperty since the objects go back to JSON strings after merging.Any suggestions to help me pull every last once of performance from this would be greatly appreciated.var utils = require(util);function mergeObjs(def, obj) {  if (typeof obj == 'undefined') {    return def;  } else if (typeof def == 'undefined') {    return obj;  }  for (var i in obj) {    // if its an object    if (obj[i] != null && obj[i].constructor == Object)    {      def[i] = mergeObjs(def[i], obj[i]);    }    // if its an array, simple values need to be joined.  Object values need to be remerged.    else if(obj[i] != null && utils.isArray(obj[i]) && obj[i].length > 0)    {      // test to see if the first element is an object or not so we know the type of array we're dealing with.      if(obj[i][0].constructor == Object)      {        var newobjs = [];        // create an index of all the existing object IDs for quick access.  There is no way to know how many items will be in the arrays.        var objids = {}        for(var x= 0, l= def[i].length ; x < l; x++ )        {          objids[def[i][x].id] = x;        }        // now walk through the objects in the new array        // if the ID exists, then merge the objects.        // if the ID does not exist, push to the end of the def array        for(var x= 0, l= obj[i].length; x < l; x++)        {          var newobj = obj[i][x];          if(objids[newobj.id] !== undefined)          {            def[i][x] = mergeObjs(def[i][x],newobj);          }          else {            newobjs.push(newobj);          }        }        for(var x= 0, l = newobjs.length; x<l; x++) {          def[i].push(newobjs[x]);        }      }      else {        for(var x=0; x < obj[i].length; x++)        {          var idxObj = obj[i][x];          if(def[i].indexOf(idxObj) === -1) {             def[i].push(idxObj);          }        }      }    }    else    {      def[i] = obj[i];    }  }  return def;}The object samples to merge:var obj1 = {            name : myname,            status : 0,            profile: { sex:m, isactive : true},            strarr:[one, three],            objarray: [                {                    id: 1,                    email: a1@me.com,                    isactive:true                },                {                    id: 2,                    email: a2@me.com,                    isactive:false                }            ]        };        var obj2 = {            name : myname,            status : 1,            newfield: 1,            profile: { isactive : false,  city: new York},            strarr:[two],            objarray: [                {                    id: 1,                    isactive:false                },                {                    id: 2,                    email: a2modified@me.com                },                {                    id: 3,                    email: a3new@me.com,                    isactive : true                }            ]        };Once merged, this console.log(mergeObjs(obj1, obj2)) should produce this:{ name: 'myname',  status: 1,  profile: { sex: 'm', isactive: false, city: 'new York' },  strarr: [ 'one', 'three', 'two' ],  objarray:    [ { id: 1, email: 'a1@me.com', isactive: false },     { id: 2, email: 'a2modified@me.com', isactive: false },     { id: 3, email: 'a3new@me.com', isactive: true } ],  newfield: 1 }
How to Optimize Merge of Two Objects That Include Arrays of Objects
javascript;node.js
I think the following is doing the same thing, you'll need to check it. It should be pretty fast, it just references objects that don't exist on the target. I changed names from def and obj to target and source because they make more sense to me.I also included as simple isArray function. Note that I don't like using the constructor property as it's public and you might get an own property rather than the inherited one, so I changed the test for object.If you test of an object, then for an array, what falls through should be a primitve. There are a lot of assumptions here, I'd implement a bit more checking to make sure I was getting what I expected.function isArray(o) {  return Object.prototype.toString.call(o) == [object Array];}// Assumes that target and source are either objects (Object or Array) or undefined// Since will be used to convert to JSON, just reference objects where possiblefunction mergeObjects(target, source) {  var item, tItem, o, idx;  // If either argument is undefined, return the other.  // If both are undefined, return undefined.  if (typeof source == 'undefined') {    return source;  } else if (typeof target == 'undefined') {    return target;  }  // Assume both are objects and don't care about inherited properties  for (var prop in source) {    item = source[prop];    if (typeof item == 'object' && item !== null) {      if (isArray(item) && item.length) {        // deal with arrays, will be either array of primitives or array of objects        // If primitives        if (typeof item[0] != 'object') {          // if target doesn't have a similar property, just reference it          tItem = target[prop];          if (!tItem) {            target[prop] = item;          // Otherwise, copy only those members that don't exist on target          } else {            // Create an index of items on target            o = {};            for (var i=0, iLen=tItem.length; i<iLen; i++) {              o[tItem[i]] = true            }            // Do check, push missing            for (var j=0, jLen=item.length; j<jLen; j++) {              if ( !(item[j] in o) ) {                tItem.push(item[j]);              }             }          }        } else {          // Deal with array of objects          // Create index of objects in target object using ID property          // Assume if target has same named property then it will be similar array          idx = {};          tItem = target[prop]          for (var k=0, kLen=tItem.length; k<kLen; k++) {            idx[tItem[k].id] = tItem[k];          }          // Do updates          for (var l=0, ll=item.length; l<ll; l++) {            // If target doesn't have an equivalent, just add it            if (!(item[l].id in idx)) {              tItem.push(item[l]);            } else {              mergeObjects(idx[item[l].id], item[l]);            }          }          }      } else {        // deal with object        mergeObjects(target[prop],item);      }    } else {      // item is a primitive, just copy it over      target[prop] = item;    }  }  return target;}