function SmartUpdate(obj, newObj, override){ // frist check whether the origin object is null if(obj == null) { if(newObj == null) { if(override) return null; return obj; } else return newObj; } // then check whether the target object is null if(newObj == null) { if(override) return null; return obj; } // then do object value assign if(typeof obj === 'object' && typeof newObj === 'object'){ for(var key in obj) { // first check all key:value pair in target obj if(newObj[key] != null) { if(typeof newObj[key] === 'object') obj[key] = SmartUpdate(obj[key], newObj[key]); else obj[key] = newObj[key]; } else if((newObj[key] === null && newObj[key] !== undefined) || override){ obj[key] = newObj[key]; } } for(var key in newObj) { // then check all key:value pair in newObj, see if there are anything to add // only assign the value when it is empty. if(obj[key] == null) obj[key] = newObj[key]; } return obj; } else{ // just going to assign the value because they are not object return newObj; } }
Updated at Feb 26th, 2020: Even the target key-value pair is null, the function will still merge 2 objects correctly.
Example:
SmartUpdate({“a”: 1, “b”: 2, “c”: 3}, {“c”: null}) => {“a”: 1, “b”: 2, “c”: null}