浅拷贝
对引用对象的引用,拷贝后的对象发生变化之后原对象也变化,反之也是
深拷贝
深拷贝就是对引用对象的完全拷贝,而不是引用,则改变拷贝后的对象之后原对象不改变,反之也是。
实现深拷贝的方式:
JSON``.parse(JSON.stringify(obj))- 利用递归实现
JSON.parse(JSON.stringify(obj))
JSON.Stringify() 将js值或对象转为json字符串,JSON.parse()将json字符串转为js值或对象
var obj = {
a: 10,
b: 20,
};
const newObj = JSON.parse(JSON.stringify(obj));
console.log(newObj);// {a: 10, b: 20}
newObj.a = 33;
console.log(newObj.a);//33
console.log(obj.a);//10
上面的例子所示,这种方法是可以进行深拷贝的,但是它只能适用于一些简单的情况。比如以下例子就不可以
var obj = {
a: 10,
b: 20,
say() {
console.log("hahaha");
},
};
const newObj = JSON.parse(JSON.stringify(obj));
console.log(newObj);// {a: 10, b: 20}
从这个例子我们可以看到JSON``.parse(JSON.stringify(obj)) 这种方式的深拷贝是不能拷贝对象中的方法,会把对象中的方法给忽略掉。在MDN官方解释JSON.stringify(obj) 在转换过程中会忽略掉 undefined、function、symbol
所以,有些情况这种方式是不行的。
递归方式
递归方式:对每一层的数据实现创建对象然后给对象赋值。
var obj = {
a: 10,
b: 20,
say() {
console.log("hahaha");
},
};
var arr = [
"10",
{
a: 10,
},
[11],
];
function deepCopy(obj) {
let newObj = obj.constructor === Array ? [] : {};
for (key in obj) {
if (obj[key] && typeof obj[key] === "object") {
newObj[key] = deepCopy(obj[key]);
} else {
newObj[key] = obj[key];
}
}
return newObj;
}
const newObj = deepCopy(obj);
newObj.a = 30;
console.log(newObj);// {a: 30, b: 20, say: ƒ}
console.log(obj);// {a: 10, b: 20, say: ƒ}
console.log(deepCopy(arr));// (3) ["10", {…}, Array(1)]
javaScript中的拷贝方法
- concat() 连接多个数组,它不会修改已存在的数组的,而是返回一个新数组。但是如果里面的数组是多层的,第一层虽然不会改变原来的,但是深层的对象会改变的。
- slice() 数组截取,和concat一样,一层没事,多层不行。
- ... 展开运算符,也是对第一层深拷贝,深层浅拷贝(只是引用