浅谈对象(数组)的深克隆和浅克隆

浅谈对象(数组)的深克隆和浅克隆

浅克隆

  • object.assign()
  • Array.prototype.concat()
  • Array.prototype.slice()

深克隆

  • JSON.stringify 和 JSON.parse
  • Object.assign()
  • 通过JQuery中的extend方法实现深拷贝
  • lodash.cloneDeep()实现深拷贝
  • 递归

注意:当对象只有一层结构的时候,使用Object.assign()是深拷贝,但是对象里面要是有子对象,就是浅拷贝

浅克隆

浅拷贝值复制某个对象的指针,而不是复制对象本身,新旧对象还是使用共同的内存,深拷贝为对象创建另一个一样的对象,修改新对象不会更改旧对象。

所以当浅拷贝的对象中含有二级对象的时候,二级对象的值其实是一个引用地址,该引用地址指向堆内存,当我们拷贝到时候,也是直接考的这个引用地址,所以修改堆中的数据的时候对原始对象和拷贝后的对象都有影响。

以下面这个obj为例,画个图相信大家就懂了。
在这里插入图片描述

1、object.assign()
使用Object.assign()是浅拷贝,当对象只有一层的时候是深拷贝,但是有子结构就是浅拷贝

  let obj = {
     name:'bella',
     addr:{
        province:'cd',
        city:'df'
     },
     age:13
  }
  let clone = Object.assign({},obj);
  clone.addr.city = 'aaa';
  console.log(obj.addr.city);// aaa

2、Array.prototype.concat()

  let arr = [1, 3, {
      username: 'kobe'
      }];
  let arr2=arr.concat();    
  arr2[2].username = 'wade';
  console.log(arr[2].username);// wade

3、Array.prototype.slice()

  let arr = [1,3,{
     username:'bella'
  }];
  let arr2 = arr.slice();
  arr2[2].username = 'dada';
  console.log(arr[2].username);//dada

深克隆

1、JSON.stringify 和 JSON.parse

用JSON.stringify把对象转换成字符串,再用JSON.parse把字符串转换成新的对象

可以转成JSON格式的对象才能使用这种方法,如果对象中包含function或者RegExp、Date这些就不能使用这个方法

  function deepClone(obj){
     let _obj = JSON.stringify(obj);
     let objClone = JSON.parse(_obj);
     return objClone
  }

2、Object.assign()拷贝

当对象中只有一级属性的时候,就是深拷贝,要是有二级属性,在二级属性以后,就是浅拷贝。

3、通过JQuery中的extend方法实现深拷贝

  let $ = require("./jquery");
  let obj1 ={
     a:1,
     b:{
        f:{
           g:1
        }
     },
     c:[1,2,3]
  }
  
  let obj2 = $.extend(true,{},obj1);

4、lodash.cloneDeep()实现深拷贝

  let _ = require('lodash');
  let obj1 = {
      a: 1,
      b: { f: { g: 1 } },
      c: [1, 2, 3]
  };
  let obj2 = _.cloneDeep(obj1);

5、递归

原理:遍历对象、数组知道里边都是基本数据类型,然后再去复制,就是深度拷贝

这里传过来的obj,要是 是fn(比如)的实例,并且obj.constructor就是fn,所以这里的newObj就是在创建fn的另一个实例(高逼格)

function deepClone(obj) {
    // 不直接创建空对象目的:克隆的结果和之前保持相同的所属类 
    var newObj = new obj.constructor;
    if(obj === null) return null;
    if(typeof obj !=='object') return obj;
    if(obj instanceof RegExp) return new RegExp();
    if(obj instanceof Date) return new Date();

    for(let key in obj){
        if(obj.hasOwnProperty(key)){
            newObj[key] = deepClone(obj[key])
        }
    }
    return newObj;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值