在js中我们都知道,引用数据类型的变量都是存放的地址,那么如何实现对一个数组或者对象的复制呢?如果直接变量赋值,并不会产生一个新的对象出来,这里就需要用到对象的浅拷贝和深拷贝知识点。
数组的浅拷贝:
1. [...arr] 扩展运算符
2. arr.concat() 返回新的数组
3. arr.slice() 返回新的数组,从头截取到尾
4. Array.from(arr) 返回新的数组
对象的浅拷贝:如果对象中一个属性还是对象,那么属性对象就不能被拷贝,例如下面代码块的例子。
1. {...obj} 扩展运算符
2. Object.assign({}, obj) 返回新对象,利用对象合并实现对象浅拷贝
const obj = {
name: '张三',
age: 12,
address: '上海',
child: {
name: '李华',
age: 3
}
};
const obj1 = {...obj}
// Object.assign()
const obj2 = Object.assign({}, obj);
obj1.age = 13;//这里会发现修改的是obj child的age,并不是新的对象的值说明child属性对象没有被拷贝出来。
obj2.age = 14;
obj.child.age = 200;
console.log(obj);
console.log(obj1);
console.log(obj2);
对象的深拷贝:
<script>
// 创建对象
const obj = {
name: '张三',
age: 10,
address: '北京',
child: {
name: '李四',
age: 3
},
users: [1,3,5,7]
};
// 专门判读对象的类型
function getObjectType(data) {
return Object.prototype.toString.call(data).slice(8, -1);
}
// 实现对象的深拷贝
function deepClone(data) {
// 判断data是Object是数组还是其他
if (getObjectType(data) === 'Object') {
var res = {}; // 创建新的空对象
} else if (getObjectType(data) === 'Array') {
var res = []; // 创建新的空数组
} else {
return data;
}
// 对传入的data进行遍历
for (let i in data) {
res[i] = deepClone(data[i]);
}
// 返回结果
return res;
}
// 对 obj 进行深拷贝
const obj1 = deepClone(obj);
obj.child.age = 200;
obj.users[2] = 'hello';
console.log(obj);
console.log(obj1);