引用数据类型的深拷贝与浅拷贝

395 阅读2分钟

JS的数据类型分为基本数据类型引用数据类型,基本数据类型存放在 中,而引用类型存放在 中.

深拷贝与浅拷贝

浅拷贝(浅克隆) 对象a赋值给对象b 修改对象a的内容 对象b也会改变

深拷贝(深克隆) 对象a赋值给对象b 修改对象a的内容 对象b不会改变

我们现在举例一个个基本数据类型变量a

a = 1,那我们可以看到在栈中生成了a变量,值为1。

当我们声明变量b = a时,栈中开辟了b的内存。
所以 当你修改a的值时,b的值不会随之发生变化,他们有着自己的内存

引用数据类型名存在栈中 值存在堆中 栈会提供地址指向堆内存中的值

b = a进行拷贝时 给予b的不是a的值 而是a的引用地址
我们a[0]=1时进行数组修改时,由于a与b指向的是同一个地址,所以自然b也受了影响,这就是浅拷贝
我们要在堆中开辟一个新内存存放b的值,这才能实现深拷贝

实现深拷贝

深拷贝

  1. JSON.stringify() JSON.parse()
  2. deepClone()
  3. ...扩展运算符

递归进行深拷贝

//深拷贝
function deepClone(obj){
    //判断是否为对象 不是对象 直接返回 
    if(obj && typeof(obj) ==='object'){
        //定义容器接受对象内容 判断是数组或对象
        var objClone = Array.isArray(obj) ? []:{};
        //对象进行循环
            for(key in obj){
                //如果对象内的项为对象 重新进行接受
                if(obj[key]&&typeof(obj[key]) === 'object'){
                    //递归赋值
                    objClone[key] = deepClone(obj[key]);
                }
                //是数组直接赋值
                else{
                    objClone[key] = obj[key];
                } 
            }
    }
    else{
        //非数组或非对象 直接赋值返回
        objClone = obj
    }
    return objClone;
}

JSON方法实现深拷贝

 var p = {
        name:'xw',
        weight:'123kg'
    }
    //将p转化为字符串赋值给p1
    var p1 = JSON.stringify(p);
    //将p1转化为对象
    p1 = JSON.parse(p1);
    //改变p的内容 p1是否随之改变
    p.name = 'lihua'
    console.log(p);//{name: "lihua", weight: "123kg"}
    console.log(p1);//{name: "xw", weight: "123kg"}