Javascript浅拷贝与深拷贝

 

首先深拷贝和浅拷贝只针对像 Object, Array 这样的复杂对象的。简单来说,浅拷贝只拷贝一层对象的属性,而深拷贝则递归拷贝了所有层级。

对于字符串类型,浅拷贝是对值的拷贝,对于对象来说,浅拷贝只拷贝对象的地址,并没有开辟新的栈,也就是拷贝的结果是两个对象指向同一个地址,修改其中一个对象的属性,则另一个对象的属性也会改变,深拷贝则是开辟新的栈空间,两个对象对应两个不同的地址,修改一个对象的属性,不会改变另一个对象的属性

深拷贝,它不仅将原对象的各个属性逐个拷贝出去,而且将原对象各个属性所包含的对象也依次采用深拷贝的方法递归拷贝到新对象上,如下图:

下面代码介绍一下如何实现深浅拷贝:

1、浅拷贝

<script>
        //浅拷贝只是拷贝一层,更深层次对象级别的只拷贝引用
        //深拷贝拷贝多层,每一级别的数据都拷贝
        var obj = {
            id:1 ,
            name: 'andy',
            msg:{
                age:18
            }
        }
        var o = {};
        for (var k in obj){
            // k 是属性名 obj[k]属性值
            o[k] = obj[k];
        }
    </script>

2、实现浅拷贝的另一种方法(  语法糖的方法利用Object.assign(target,...sources) )

 <script>
        //浅拷贝只是拷贝一层,更深层次对象级别的只拷贝引用
        //深拷贝拷贝多层,每一级别的数据都拷贝
        var obj = {
            id:1 ,
            name: 'andy',
            msg:{
                age:18
            }
        }
        var o = {};
        /* for (var k in obj){
            // k 是属性名 obj[k]属性值
            o[k] = obj[k];
        }
        
        console.log(o); //只属于浅拷贝
        console.log(obj); */
        //Object.assign(target,...sources) es6新增方法可以浅拷贝
        //两个参数 第一个是你要拷贝的地方 第二个是你要拷贝的对象
        //新的语法糖 直接进行浅拷贝
        Object.assign(o,obj); /* assign */
        console.log(o); //只属于浅拷贝
        console.log(obj);

    </script>

3、深拷贝的实现方法

(1)、利用递归

   递归方法实现深度克隆原理: 遍历对象、数组直到里边都是基本数据类型,然后再去复制,就是深度拷贝

 <script>
         var obj = {
            id:1 ,
            name: 'andy',
            msg:{
                age:18
            },
            color:['pink', 'red']
        }
        var o = {};
        //封装函数完成深度拷贝 递归的操作
        function dep(newobj,oldobj) {
            for(var k in oldobj){
                //判断属性值属于那种数据类型
                //1.获取属性值
                var item = oldobj[k];
                //判断是否是数组  
                if (item instanceof Array){
                    newobj[k] = [];
                    dep(newobj[k],item)
                }else if (item instanceof Object){
                    newobj[k] = {};
                    dep(newobj[k],item)
                }else{
                    newobj[k] = item;
                }            
            }
        }
        dep(o,obj);
        console.log(o);
        o.msg.age=20;
        console.log(obj);
        //深拷贝不会影响原来的数据
        //深拷贝 使用遍历递归的方法 
        //深入到内部进行判断,直到判断到单个的对象为止
        
    </script>

       (2)、利用JSON实现深拷贝

function deepClone2(obj) {
    var _obj = JSON.stringify(obj),
    objClone = JSON.parse(_obj);
  return objClone;
}

      (3)、直接使用var newObj = Object.create(oldObj)

function deepClone(initalObj, finalObj) {    
  var obj = finalObj || {};    
  for (var i in initalObj) {        
    var prop = initalObj[i]; 
    if(prop === obj) {            
      continue;
    }        
    if (typeof prop === 'object') {
      obj[i] = (prop.constructor === Array) ? [] : Object.create(prop);
    } else {
      obj[i] = prop;
    }
  }    
  return obj;
}

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

李遇·

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值