JSFiddle - React, Tailwind, and code Playground
JavaScript
var obj1 = {"a":{"b":"c", "e":"f"}};
var obj2 = {"a":{"b":"x"}};
$('body').append("original obj1: " + JSON.stringify(obj1) + "<br>");
$('body').append("original obj2: " + JSON.stringify(obj2) + "<br><br>");
$('body').append("smartJSONextend(obj1, obj2); => " + JSON.stringify(smartJSONextend(obj1, obj2)) + "<br>");
$('body').append("$.extend({}, obj1, obj2); =>" + JSON.stringify($.extend({}, obj1, obj2)) + " --- $.exetend loses {e:'f'}<br>");
$('body').append("$.merge(obj1, obj2); ->", JSON.stringify($.merge(obj1, obj2)), " --- $.merge doesn't work on objects ('b':'c' is still there)");
$('body').append("<br><br>smartJSONextend keeps siblings if only a leaf is affected");
function smartJSONextend(obj1, obj2) {
//clone
var mergedObj = JSON.parse(JSON.stringify(obj1));
(function recurse(currMergedObj, currObj2){
var key;
for (key in currObj2) {
if (currObj2.hasOwnProperty( key )){
//keep path alive in mergedObj
if (!currMergedObj[key]){
currMergedObj[key] = undefined;
}
if ( typeof currObj2[key] === "string" || typeof currObj2[key] === "number" || typeof currObj2[key] === "boolean" ){
//overwrite if obj2 is leaf and not nested
currMergedObj[key] = currObj2[key];
} else if (typeof currObj2[key] === "object"){
//obj2 is nested
//and currMergedObj[key] is undefined, sync types
if (!currMergedObj[key]) {
//obj2[key] ifArray
if(currObj2[key].length !== undefined){
currMergedObj[key] = [];
} else {
currMergedObj[key] = {};
}
}
recurse(currMergedObj[key], currObj2[key]);
}
}
}
}(mergedObj, obj2));
...