预备知识回顾,js数据类型:
基本数据类型:Undefined、Null、Boolean、Number、String、Symbol
引用数据类型:Object
基本类型:存放在栈内存中的简单数据段,数据大小确定,内存空间大小可以分配,是直接按值存放的,所以可以直接访问。
引用类型:存放在堆内存中的对象。在栈内存中变量保存的是一个指针,指向对应在堆内存中的地址。当访问引用类型的时候,要先从栈中取出该对象的地址指针,然后再从堆内存中取得所需的数据。
浅拷贝
浅拷贝对象只会被克隆最外部的一层,至于更深层的对象,则依然是通过引用指向同一块堆内存.
注意与赋值号"="的区别,赋值号只是将指针改变,其引用的仍然是同一个对象,而浅拷贝则是重新创建了新对象。
function shallowClone(obj) {
const tempObj = {}
for (let i in obj) {
tempObj[i] = obj[i]
}
return tempObj
}
// 被拷贝的对象
const oldObj = {
a: 1,
b: { c: 1 },
}
const newObj = shallowClone(oldObj)
oldObj.a = 2
oldObj.b.c = 2
console.log(newObj)
// 结果
/*
{
a:1
b:{c: 2}
}
*/
另外,Object.assign()也可以实现浅拷贝
深拷贝
1.JSON.parse方法
const newObj = JSON.parse(JSON.stringify(oldObj));
这是一个比较简单且常用的深拷贝方法,有许多坑在里面
- 无法实现对Function,RegExp等特殊对象的拷贝
- 会丢失对象的constructor属性,所有的构造函数都会指向Object
- 如果对象有循环引用就会报错
2. 自定义深拷贝函数
拷贝的时候判断一下属性值的类型,如果是对象,我们递归调用深拷贝函数
var deepCopy = function(obj) {
if (typeof obj !== 'object') return;
var newObj = obj instanceof Array ? [] : {};
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
newObj[key] = typeof obj[key] === 'object' ? deepCopy(obj[key]) : obj[key];
}
}
return newObj;
}