JavaScript深拷贝与浅拷贝

48 阅读1分钟

想要理解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,实现了深拷贝