工作中javascript因深拷贝问题,遇到相当大的麻烦,特地自己写了一个。目前应该是比较完美的解决方案,解构多重嵌套,对数组、函数、Date、RegExp、null、原型链都有进行处理。代码如下:
function objDeepCopy(obj) {
// 对null进行处理
if (obj === null) return null;
//如果是值类型,直接返回值
if (typeof obj !== 'object') return obj;
// 对Date对象进行处理
if (obj.constructor === Date) return new Date(obj);
// 对RegExp对象进行处理
if (obj.constructor === RegExp) return new RegExp(obj);
// 拷贝其构造器,获取该对象的原型,使原型也继承下来
var newObj = new obj.constructor();
for (var key in obj) {
//防止遍历时,拷贝到__proto__的可见属性
if (obj.hasOwnProperty(key)) {
var val = obj[key];
newObj[key] = typeof val === 'object' ? objDeepCopy(val) : val;
}
}
return newObj;
};
下面是测试数据:
var a = {
"deadLine": "infinite",
"data": {
"params": {
"amount": "6.00",
"discounts": [{
"desc": "随机立减优惠",
"offstAmt": "2.11"
}],
"mchntNm": "3",
"orderDesc": "随机立减",
"orderDetail": "{\"outTradeNo\":\"20191010\",\"settleAt\":\"600\",\"voucherNum\":\"2019101020191010\",\"currencyCode\":\"156\"}",
"pointsAt": "2.11",
"testAmount": "6.00",
"testAt": "3.89",
"personalObj": {
"txt": "测试",
"No": 1,
arr: [1, 2, 3, 4, 5]
},
nullObj: null,
regObj: new RegExp(),
fuc: function () {
var a = 100;
}
},
"resp": "00"
}
};
var b = objDeepCopy(a);
a.data.params.discounts[0].offstAmt = "900元";
a.data.params.orderDesc = "修改过";
a.data.params.pointsAt = "100元";
a.data.params.personalObj.No = 100;
a.data.params.personalObj.arr[3] = 99;
a.data.params.fuc = function () {
var b = 666
};
console.log(b.data.params.discounts[0].offstAmt); // 2.11
console.log(b.data.params.orderDesc); // 随机立减
console.log(b.data.params.pointsAt); // 2.11
console.log(b.data.params.personalObj.No); // 1
console.log(b.data.params.personalObj.arr[3]); // 4
console.log(b.data.params.fuc); //ƒ () {var a = 100;}
用了很多方法,$.extend() 和 Object.assing() 都是浅拷贝,最后经过测试决定用上面的方法。