深浅拷贝
浅拷贝
仅仅复制了引用,彼此之间的操作会互相影响
-
Array.prototype.slice()
-
Array.prototype.concat()
对于一维Array来说,这两种方法似乎是深拷贝,但当数组为二维甚至多维的时候,只是对数组进行复制引用,所以,Array的slice以及concat方法都是浅拷贝
let arr = [1, 2, 3, 4]
let arr1 = arr.slice()
console.log(arr === arr1) // false
arr1[0] = 2
console.log(arr) // [1, 2, 3, 4]
console.log(arr1) // [2, 2, 3, 4]
// concat 同理
let arr = [[1, 2], 2, 3, 4]
let arr1 = arr.slice()
console.log(arr === arr1) // false
arr1[0][0] = 2
console.log(arr) // [[2, 2], 2, 3, 4]
console.log(arr1) // [[2, 2], 2, 3, 4]
// concat 同理
深拷贝
在堆中重新分配内存,不同的地址,相同的值,互不影响(复制的实例)
- JSON.stringify() 和 JSON.parse
JSON.stringify()
将js对象序列化为一个json字符串
JSON.parse()
将json对象反序列化为一个js对象
let obj = {
a: 1,
b: 2,
c: {
d: 3,
f: [1, 2, 3],
g: {
f: 4
}
}
}
let obj1 = JSON.parse(JSON.stringify(obj))
obj.c.d = 2
console.log(obj) // {a: 1, b: 2, c: {d: 2, f: [1, 2, 3], g: {f: 4}}}
console.log(obj1) // {a: 1, b: 2, c: {d: 3, f: [1, 2, 3], g: {f: 4}}}
- 利用递归实现对象或数组的深拷贝
let obj = {
a: 1,
b: 2,
c: {
d: 3,
f: [1, 2, 3],
g: {
f: 4
}
}
}
function deepClone (obj) {
if (!obj && typeof obj !== 'object') return
const targetObj = Array.isArray(obj) ? [] : {}
for (let key in obj) {
// 对对象的自有属性进行拷贝
if (obj.hasOwnProperty(key)) {
if (obj[key] && typeof obj[key] === 'object') {
targetObj[key] = deepClone(obj[key])
} else {
targetObj[key] = obj[key]
}
}
}
return targetObj
}
let obj2 = deepClone(obj)
obj2.c.f = 'array'
console.log(obj) // {a: 1, b: 2, c: {d: 3, f: [1, 2, 3], g: {f: 4}}}
console.log(obj2) // {a: 1, b: 2, c: {d: 3, f: 'array', g: {f: 4}}}
Object.assign()与Array.prototype.slice()类似,对于一层的对象是深拷贝,二层及二层以上则是浅拷贝,所以,Object.assign()是浅拷贝