概念:
- 浅拷贝:只拷贝最外面一层的数据;更深层次的对象,只拷贝引用。
-
深拷贝:拷贝多层数据;每一层级别的数据都会拷贝。
一、浅拷贝
js 常见的浅拷贝方法
1.Object.assign()
let oldObj = {
inObj: {a: 1, b: 2}
}
let newObj = Object.assign({}, oldObj)
newObj.inObj_2 = {a: 1, b: 2}
newObj.inObj.a = 2
console.log(oldObj) // { inObj: { a: 2, b: 2 } }
console.log(newObj) // { inObj: { a: 2, b: 2 }, inObj_2: { a: 1, b: 2 } }
2. 扩展运算符
let oldObj = {
inObj: {a: 1, b: 2}
}
let newObj = {...oldObj}
newObj.inObj_2 = {a: 1, b: 2}
newObj.inObj.a = 2
console.log(oldObj) // { inObj: { a: 2, b: 2 } }
console.log(newObj) // { inObj: { a: 2, b: 2 }, inObj_2: { a: 1, b: 2 } }
const oldArr = ["One", "Two", "Three",{name:"Four"}]
const newArr = [...oldArr]
newArr[1] = "love";
newArr[3].name = 'Five'
console.log(oldArr) // ['One', 'Two', 'Three', { name: 'Five' } ]
console.log(newArr) // [ 'One', 'love', 'Three', { name: 'Five' } ]
3 .Array.concat()
const oldArr = ["One", "Two", "Three",{name:"Four"}]
const newArr = oldArr.concat(["Six"])
newArr[1] = "love";
newArr[3].name = 'Five'
console.log(oldArr) // ['One', 'Two', 'Three', { name: 'Five' } ]
console.log(newArr) // [ 'One', 'love', 'Three', { name: 'Five' }, 'Six' ]
4. Array.slice()
const oldArr = ["One", "Two", "Three",{name:"Four"}]
const newArr = oldArr.slice(0)
newArr[1] = "love";
newArr[3].name = 'Five'
console.log(oldArr) // ['One', 'Two', 'Three', { name: 'Five' } ]
console.log(newArr) // [ 'One', 'love', 'Three', { name: 'Five' } ]
js 常见的深拷贝方法
1 _.cloneDeep()
const _ = require('lodash');
let oldObj = {
a: 1, b: 2,c:{value:3}
}
let newObj = _.cloneDeep(oldObj)
newObj.a = 2
newObj.c.value = 4
console.log(oldObj) // { a: 1, b: 2, c: { value: 3 } }
console.log(newObj) // { a: 2, b: 2, c: { value: 4 } }
2 .JSON.stringify()
const oldObj = {
name: 'A',
name1: {value:3}
}
const newObj = JSON.parse(JSON.stringify(oldObj));
newObj.name = 'B'
newObj.name1.value = 4
console.log(oldObj)
// {name: 'A',name1: { value: 3 }}
console.log(newObj)
// { name: 'B', name1: { value: 4 } }
3 .手写递归方法
function cloneDeep(obj, hash = new WeakMap()){
if(obj instanceof Date) return new Date(obj);
if (obj instanceof RegExp) return new RegExp(obj);
if(!obj || typeof obj !== 'object') return obj;
if(hash.get(obj)) return hash.get(obj);
// 找到的是所属类原型上的constructor,而原型上的 constructor指向的是当前类本身
let newObj= new obj.constructor();
hash.set(obj,newObj);
for(let key in obj) {
if(obj.hasOwnProperty(key)){
newObj[key] = cloneDeep(obj[key],hash)
}
}
return newObj
}