浅拷贝
-
浅拷贝只复制指向某个对象的指针,而不复制对象本身,新旧对象还是共享同一块内存
-
深拷贝会另外创造一个一模一样的对象,新对象跟原对象不共享内存,修改新对象不会改到原对象
-
Object.assign
- 当object只有一层的时候,是深拷贝
var obj = { a: {a: "kobe", b: 39} }; var initalObj = Object.assign({}, obj); initalObj.a.a = "wade"; console.log(obj.a.a); //wadelet obj = { username: 'kobe' }; let obj2 = Object.assign({},obj); obj2.username = 'wade'; console.log(obj);//{username: "kobe"} -
Array.prototype.concat()
- 不修改原数组,只会返回浅拷贝的新数组
let arr = [1, 3, { username: 'kobe' }]; let arr2=arr.concat(); arr2[2].username = 'wade'; console.log(arr); -
Array.prototype.slice()
- 不修改原数组,只会返回浅拷贝的新数组
let arr = [1, 3, { username: ' kobe' }]; let arr3 = arr.slice(); arr3[2].username = 'wade' console.log(arr); -
ES6 ...
赋值
- 赋的其实是该对象的在栈中的地址,而不是堆中的数据
let arr = [1, 2, 3, 4, 5];
// = 赋值
let newArr = arr;
newArr.push(6);
// console.log(arr, newArr)
// 基本类型不存在深浅拷贝
let a = 1;
let b = a;
b = 2;
// console.log(a)
解构赋值是是浅拷贝
-
解构的原对象
-
一维数组或对象 => 深拷贝
-
多维数组或对象 => 浅拷贝
-
let arr2 = [[1, 2], [2, 3], [3, 4]];
let newArr2 = [...arr2]; // ES6 => 解构赋值
newArr2[0].push(666)
console.log(arr2, newArr2)
// [[1, 2, 666], [2, 3], [3, 4]] [[1, 2, 666], [2, 3], [3, 4]]
深拷贝
JSON.parse(JSON.stringify(obj))
-
最快捷的深拷贝方法 80%的场景
let obj = { a: { aa: 1, bb: 2 }, b: 3, c: 4, } let newObj = JSON.parse(JSON.stringify(obj)); newObj.a.aa = 666; // 方法不能拷贝 // function => "function" console.log(obj, newObj)
-
无法处理循环引用
- 即对象的属性之间相互引用,导致循环引用部分丢失,或者导致一个无限循环的结构,最终导致堆栈溢出
- 不能处理函数
函数库lodash
-
_.cloneDeep用来做 Deep Copy
var _ = require('lodash'); var obj1 = { a: 1, b: { f: { g: 1 } }, c: [1, 2, 3] }; var obj2 = _.cloneDeep(obj1); console.log(obj1.b.f === obj2.b.f); // false
手写 深拷贝 → 引用数据类型(数组/对象)
function deepClone (source) {
// 容器
// [] => Array(基类)() => Object
// 外层定义
const targetObj = source.constructor === Array ? [] : {};
for (let keys in source) {
// 判断是不是夹心的
if (source.hasOwnProperty(keys)) {
// object => 对象,数组,内层定义
if (source[keys] && typeof source[keys] === "object") {
// targetObj[keys] = source[keys].constructor === Array ? [] : {};
// 递归
targetObj[keys] = deepClone(source[keys])
} else {
// 基本类型,直接赋值
targetObj[keys] = source[keys];
}
}
}
return targetObj;
}
// obj => Object [] => Array // 基类
let obj2 = {
a: { aa: 1, bb: 2 },
b: 3,
c: 4,
}
let newObj222 = deepClone(obj2);
newObj222.a.bb = 6688;
console.log(obj2, newObj222)