想要理解JavaScript中的深拷贝和浅拷贝,首先需要知道JavaScript的数据类型。
JavaScript的数据类型分为两大类:基本数据类型和引用数据类型, 这两种数据类型是怎样存储的呢?
-
基本数据类型
存储在栈中
-
引用数据类型
数据存储在堆中,在栈中存储一个指向堆中数据的内存地址
先看一下浅拷贝:
const obj = {
age:'20',
name:'Bob',
hobbies:['学习','思考','实践']
}
const obj1 = obj;
obj1.hobbies[0] = '吃饭',
console.log(obj.hobbies[0]);
上述代码在控制台打印的结果是 吃饭,可见,obj的拷贝对象obj1修改了hobbies属性,原对象的属性值也发生了改变,这是因为 obj1 = obj 这句语句只是将obj对象的引用地址拷贝给了obj1,此时,二者的内存地址相同,因此堆中对应的数据也是相同的,所以obj1发生了改变,obj也就发生了改变,这就是浅拷贝。
深拷贝:
先看代码:
//定义一个对象,用于被拷贝
const obj1 = {
age:'20',
name:'Bob',
hobbies:['学习','思考','实践']
}
//深拷贝函数
function deepClone(obj = {}){
//判断,如果传入的参数不是对象或数组,或者 是null,不做拷贝,直接返回
if(typeof obj !== 'object' || obj == null){
return obj;
}
//初始化返回数据
let result;
//判断传入对象的具体类型,如果是数组,返回结果为数组,否则,返回结果为对象
if(obj instanceof Array){
result = [];
}else {
result = {};
}
//对传入对象进行遍历
for(let key in obj){
//确保key不是原型上的属性
if(obj.hasOwnProperty(key)){
//递归调用
result[key] = deepClone(obj[key]);
}
}
return result;
}
const obj2 = deepClone(obj1);
obj2.age = 10;
console.log(obj1.age); //20
可见输出结果仍然是20,实现了深拷贝