浅拷贝和深拷贝的区别
假设 B 复制了 A,当修改 A 时,看 B 是否会发生变化,如果 B 也跟着变了,说明这是浅拷贝,如果 B 没变,那就是深拷贝。本质就是浅拷贝拷贝的是引用数据类型的引用地址。
实现浅拷贝: 赋值
实现深拷贝
- 一层深拷贝
看到有很多博客误导是深拷贝,注意以下方法只深复制了基本类型数据类型,即只深拷贝了一层,不是真正意义的深拷贝!!!
1. 扩展运算符: `[...arr]` `{...obj}`
2. `arr.slice()`
3. `arr.concat()`
4. `Array.from(arr)`
5. `Object.assign({}, obj)`
-
JSON.parse(JSON.stringify(obj))
缺点: 当值为 undefined、function、symbol 会在转换过程中被忽略 -
递归
function deepCopy(obj) {
var result = Array.isArray(obj) ? [] : {};
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
if (typeof obj[key] === 'object') {
result[key] = deepCopy(obj[key]); //递归复制
} else {
result[key] = obj[key];
}
}
}
return result;
}
-
jq 的 extend 方法
$.extend(true,{},obj)
缺点: 依赖 jquey 库 -
lodash 的
_.cloneDeep
方法
_.cloneDeep(obj)
实例
let arr = [[1, 2], 1, 2, 3, 4];
// let newArr = arr; // 浅拷贝
let newArr = [...arr]; // 一层深拷贝
// let newArr = arr.slice(); // 一层深拷贝
// let newArr = arr.concat(); // 一层深拷贝
// let newArr = Array.from(arr); // 一层深拷贝
// let newArr = deepCopy(arr); // 深拷贝
newArr[0][0] = 10;
newArr[1] = 20;
// console.log(arr, newArr);
let obj = { body: { a: 10 }, b: 1 };
// let newObj = obj; //浅拷贝
let newObj = {...obj}; // 一层深拷贝
// let newObj = Object.assign({}, obj); // 一层深拷贝
// var newObj = JSON.parse(JSON.stringify(obj)); // 深拷贝
// let newObj = deepCopy(obj); // 深拷贝
newObj.body.a = 20;
newObj.b = 2;
console.log(obj, newObj);
function deepCopy(obj) {
var result = Array.isArray(obj) ? [] : {};
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
if (typeof obj[key] === 'object') {
result[key] = deepCopy(obj[key]); //递归复制
} else {
result[key] = obj[key];
}
}
}
return result;
}
网友评论