什么是深浅
概念
深拷贝、浅拷贝只针对像Object/Array这样的对象,对于基本类型而言,可以理解为是没有深浅的区别的。
浅拷贝复制的是引用,修改对象的属性,会彼此影响。
just like this
let a = {name: 'ziv'}
let b = a // a和b指向了同一块内存
b.name = 'lucky'
console.log(a.name) // 'lucky'
console.log(b.name) // 'lucky'
深拷贝重新开辟了一个空间,修改对象的属性,彼此不会影响。
实现浅拷贝
使用内置的方法
// Object.assign()
//只能用于浅拷贝对象或者合并对象
let obj = {a:'x', b: {c: 'y'}}
let newObj = Object.assign({}, obj)
obj.b.c = 'z'
console.log(newObj) // {a:"x", b: {c: "z"}}
// Array.from()
// ...操作符
// slice()
// concat() 用于数组
let arr = [1,2, [3,4,5]]
let sliceArr = arr.slice()
let concatArr = arr.concat()
let fromArr = Array.from(arr)
let newArr = [...arr]
arr[2][1] = 'sixsix'
console.log(sliceArr) // [1,2,[3,'sixsix',5]]
console.log(concatArr) // [1,2,[3,'sixsix',5]]
console.log(fromArr) // [1,2,[3,'sixsix',5]]
使用遍历
// 对象浅拷贝
let shallowCopy = function(obj) {
// 如果不是对象,不执行拷贝
if (typeof obj !== 'object') return
// 判断对象是数组还是对象
let newObj = obj instanceof Array ? [] : {}
// 遍历obj
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
// 拷贝到新对象中
newObj[key] = obj[key]
}
}
return newObj
}
实现深拷贝
序列化反序列化
// 适用于数组还有对象,但是对于函数对象、正则对象、稀疏数组等无法进行深拷贝(而且会直接丢失相应的值),并且会抛弃对象的constructor,也就是说无论这个函数的构造函数是谁,使用这种拷贝之后,constructor都会变成Object。对循环引用同样无法处理。
let arr = ['old', 1, true, ['old1', 'old2'], {old: 1}]
let new_arr = JSON.parse(JSON.stringify(arr))
arr[3][0] = 'new1' // new_arr并不会更改
console.log(new_arr)
使用递归
// 适用于对象里面有对象
let deepCopy = function(obj) {
if (typeof obj !== 'object') return obj
let newObj = obj instanceof Array ? [] : {}
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
newObj[key] = typeof obj[key] === 'object' ? deepCopy(obj[key]) : obj[key]
}
}
return newObj
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。