用处
当我们需要对一个引用值进行复制时,我们就需要用到拷贝
例子
原始值拷贝
let a = 12
let b = a
a = 13
console.log(b) // 打印出 12
引用值拷贝(错误版)
如果我们使用与原始值相同的拷贝方法就会出现以下结果
let obj1 = {
name: "小明",
age: 17
}
let obj2 = obj1
obj1.name = "小红"
console.log(obj2.name) // 此时输出为小明
因为对 obj2 进行赋值时,仅仅复制了 obj1 的指针,而指针的指向仍然是同一个对象,所以当我们通过 obj1 改变的对象与 obj2 指向的对象是同一个对象;
浅拷贝
- es3写法
let obj1 = {
name: "小明",
age: 17
}
function simpleClone(obj) {
var cloneObj = {}
// es3 的写法
for(let i in obj) {
cloneObj[i] = obj[i]
}
return cloneObj
}
let obj2 = simpleClone(obj1)
obj1.name = "小红"
console.log(obj2.name) // 小明
console.log(obj1.name) // 小红
- es6 写法
let obj1 = {
name: "小明",
age: 17
}
function simpleClone(obj) {
var cloneObj = {}
// for(let key of Object.keys(obj1)) {
// cloneObj[key] = obj1[key]
// }
for(let [key,value] of Object.keys(obj1)) {
cloneObj[key] = value
}
return cloneObj
}
let obj2 = simpleClone(obj1)
obj1.name = "小红"
console.log(obj2.name) // 小明
console.log(obj1.name) // 小红
深拷贝
- 利用递归层层拷贝
let obj1 = {
a: 1,
b: 3,
c: {
e: {
f: 8
},
g: 4
},
h: 7
}
function deepClone(obj,cloneObj) {
var cloneObj = cloneObj || {}
for(let i in obj) {
if(typeof obj[i]=== 'object' && obj[i] !== null) {
cloneObj[i] = {}
deepClone(obj[i],cloneObj[i])
} else {
cloneObj[i] = obj[i]
}
}
return cloneObj
}
let obj2 = deepClone(obj1)
obj1.c.g = 10
console.log(obj2.c.g)
- 利用 JSON.parse() 和 JSON.stringify 先将其转化为字符串,在重新转化为对象
let obj1 = {
a: 1,
b: 3,
c: {
e: {
f: 5,
i: [1,2,4,5]
},
g: 4
},
h: 7
}
function deepClone(obj,cloneObj) {
// 利用 JSON.parse() 和 JSON.stringify 先将其转化为字符串,在重新转化为对象
return JSON.parse(JSON.stringify(obj))
}
let obj2 = deepClone(obj1)
obj1.c.e.i.push(10)
console.log(obj1);
console.log(obj2)