我有这样一个需求:将一个对象与第二个对象合并起来,如果第二个对象具有第一个对象的属性,以二个对象的值为准。
刚开始感觉这是个很简单的函数,就写成了这样:
/** * 将对象src合并至des,遇到相同的属性已des的属性为准,注意属性也要深拷贝 * @param des 目标对象 * @param src 要合并的对象 */ function merge2Object(des,src){ if(typeof(des)!="object" || typeof(src)!="object") { throw new TypeError(); } for(var prop in src){ if(des.hasOwnProperty(prop)) continue; else des[prop] = src[prop]; } }
结果后来遇到了一些错误,经过排查,发现这个函数真是一个渣:我忘记了如果value又是一个对象的话,就会将src对象的某个key对应的value引用过去。这样子可能导致src被一些不起眼的地方修改掉。所以这个函数需要改一下:
function merge2Object(des,src){ if(typeof(des)!="object" || typeof(src)!="object") { throw new TypeError(); } for(var prop in src){ if(des.hasOwnProperty(prop)) continue; else //des[prop] = src[prop]; des[prop] = deepclone(src[prop]); } }
/** *深度拷贝一个对象 *@param obj 要深度拷贝的对象 */ function deepclone(obj){ if (typeof(obj) != "object" || obj == null) //使用==涵盖null和undefined return obj; //当obj还是一个对象的时候 var re_obj = {}; for(var key in obj){ re_obj[key] = deepclone(obj[key]);//递归下去 } return re_obj; }
看来以后写东西得小心了。