针对对象或者数组的二次修改,并且不影响原数据的需求,需要用到js的拷贝,根据具体需求和业务场景来选择使用拷贝方法:
<script>
let obj = {
a: 111,
b: "abc",
c: { c1: 222 },
d: [1, 2, { d1: 111 }],
e: new Set([{ e1: 2222 }])
}
// 浅拷贝
const clone1 = { ...obj };//es6的扩展运算符
const clone2 = Object.assign({}, obj);//assign赋值
const clone3 = Object.keys(obj).reduce((prev, cur) => ({ ...prev, [cur]: obj[cur] }), {});
// 深拷贝
function deepClone(obj) {
// 获取数据类型
const type = Object.prototype.toString.call(obj);
switch (type) {
case "[object Object]": {
const newObj = {};
for (let key in obj) {
newObj[key] = deepClone(obj[key]);
}
return newObj;
}
case "object Arrary": {
return obj.map(item => deepClone(item));
}
case "object Set": {
const newObj = new Set();
obj.forEach(item => {
newObj.add(deepClone(item))
});
return newObj;
}
default:
return obj;
}
}
// 测试输出,深拷贝的值不会被影响
const cloneObj = deepClone(obj);
obj.a = 123;
console.log("a:" + obj.a, cloneObj.a, clone1.a);//a:123 111 111
obj.c.c1 = 1234;
console.log("c:" + obj.c.c1, cloneObj.c.c1, clone1.c.c1);//c:1234 222 1234
obj.e.add(1234);
obj.e.values().next().value.e1 = 1234;
console.log("e:" + obj.e, cloneObj.e, clone1.e);//e: Set(2) {{…}, 1234} Set(2) {{…}, 1234}
</script>