深浅拷贝
什么是深浅拷贝?
深浅拷贝是只针对Object和Array这样的引用数据类型的
- 浅拷贝:只进行一层关系的拷贝,如果属性是基本类型,直接拷贝基本类型的值,如果属性值是内存地址,就拷贝这个地址,新旧对象公用一块内存
- 深拷贝:进行无限层次的拷贝,会创造一个一摸一样的对象,不共享内存,修改对象不会互相影响
为什么要进行深浅拷贝?
let arr1 = arr2 = [1,2,3]
let obj1 = obj2 = {a:1, b:2, c:3}
arr1[0] = 2
obj1.a = 2
console.log(arr2[0]) // 2
console.log(obj2.a) // 2
从上面的代码可以看出:同一个Array或者Object赋值给两个不同变量时,变量指向的是同一个内存地址,改变其中一个变量的属性值,另一个也会改变。如果我们想要的是两个初始值相等但互不影响的变量,就要使用到拷贝。
深浅拷贝的使用
浅拷贝:
-
扩展运算符(ES6新语法)
let a = {c: 1} let b = {...a} a.c = 2 console.log(b.c) // 1
-
Object.assign(target, source)
将source的值浅拷贝到target目标对象上
let a = {c: 1} let b = Object.assign({}, a) a.c = 2 console.log(b.c) // 1
深拷贝:
-
JSON.stringify()
let obj = { name: 'lxy', city: { city1: '北京', city2: '上海' } } // 浅拷贝 let obj1 = {...obj} // 深拷贝 let obj2 = JSON.stringify(obj) // 改变源对象的引用类型值 obj.city.city1 = '杭州' console.log(obj1.city.city1) // 杭州 console.log(JSON.parse(obj2).city.city1) // 北京
深浅拷贝的手动实现?
浅拷贝:
循环遍历对象,将对象的属性值拷贝到另一个对象中,返回该对象。
function shallowClone(o) {
const onj = {};
for(let i in o) {
obj[i] = o[i]
}
return obj;
}
深拷贝:(简单实现)
对于深拷贝来说,就是在浅拷贝的基础上加上递归
var a1 = {
b: {
c: {
d: 1
}
}
}
function deepClone(obj) {
var target = {}
for(var i in obj) {
if(obj.hasOwnProperty(i)) {
if(typeof obj[i] === 'object') {
target[i] = deepClone(obj[i])
} else {
target[i] = obj[i]
}
}
}
return target
}