(zhuanlan.zhihu.com/p/56741046)
一、数据类型
- 基本数据类型:String、Number、Boolean、undefined、null、Symbol
- 引用数据类型:Object、Array、Function
二、浅拷贝与深拷贝
1. 什么时候需要拷贝?
在实际开发过程中,有时候我们需要使用某个变量的值,如果这个变量是基本数据类型,那直接赋值即可;如果它的值是一个对象,这个时候直接赋值是不行的,因为对象在 JavaScript 中是引用数据类型,变量中存储的是该对象在内存中的地址引用,赋值操作只是将该内存地址重新赋值给一个新的变量,这个时候两个变量实际上指向的是同一个对象。
// 定义一个对象
const info = {
name: "caohan",
age: "27",
friend: {
name: "ch"
}
};
const obj = info; // 此时 info 跟 obj 指向的是同一个对象
info.name = 'tangting'
console.log(obj.name); // tangting
这个时候我们就需要使用拷贝,将原有的对象拷贝一份。
2. 浅拷贝
创建一个新的对象,来保存所需对象的所有属性值。浅拷贝有如下实现方式:
1)Object.assign
// 定义一个对象
const info = {
name: "caohan",
age: "27",
friend: {
name: "ch"
}
};
const obj = Object.assign({}, info); // 实现了浅拷贝
info.name = "tangting";
console.log(info.name); // tangting
console.log(obj.name); // caohan
2)扩展运算符
// 定义一个对象
const info = {
name: "caohan",
age: "27",
friend: {
name: "ch"
}
};
const obj = { ...info }; // 实现了浅拷贝
info.name = "tangting";
console.log(info.name); // tangting
console.log(obj.name); // caohan
以上方法只实现了浅层的拷贝,如果对象中的属性的属性值也为引用数据类型,例如对象时,该方法就会存在问题,即:
// 如果修改 info 里面的 friend 里面的 name
// obj 里面的 friend 里面的 name 也会改变
info.friend.name = "tt";
console.log(info.friend.name); // tt
console.log(obj.friend.name); // tt
想要实现深层的拷贝,就要使用下面的方法。
3. 深拷贝
1)JSON.parse(JSON.stringify())
const info = {
name: "caohan",
age: "27",
friend: { // 属性值为对象
name: "ch"
}
};
const obj = JSON.stringify(JSON.parse(info));
info.friend.name = "tt";
console.log(info.friend.name); // tt
console.log(obj.friend.name); // caohan
这种方法可以处理属性值为对象情况,如果是数组或函数就不可以了。
2)手写递归方法
递归方法实现深度克隆原理:遍历对象、数组直到里边都是基本数据类型,然后再去复制,就是深度拷贝
3)函数库lodash
该函数库也有提供_.cloneDeep用来做 Deep Copy