深拷贝和浅拷贝的理解及各有哪些方法

一,什么是深拷贝?什么是浅拷贝?

深拷贝:会拷贝对象所有的属性,如果这个属性是一个对象的话,会继续向下拷贝,直到拷贝到基本数据类型为止,对于深拷贝的对象,当改变拷贝对象的属性值时候,不会改变原对象。

浅拷贝:只会拷贝对象的第一层属性,如果拷贝的属性是一个对象的话,只会拷贝这个对象的地址过去,改变拷贝对象中的属性时候,原对象也会改变。

二。各自有哪些方法?

深拷贝方法一:

JSON.parse(JSON.stringify()) 不能拷贝函数,时间对象,属性值为undefined等,具体看注意中列出的

      let obj = {a:3,data:{c:1,d:2}}
      let newObj = JSON.parse(JSON.stringify(obj))
      newObj.data.c = 4
      console.log(newObj,obj) //a:3,data:{c:4,d:2} ,{a:3,data:{c:1,d:2}}

注意:该方法不能拷贝如下:

1、如果obj里面存在时间对象,JSON.parse(JSON.stringify(obj))之后,时间对象变成了字符串。
2、如果obj里有RegExp、Error对象,则序列化的结果将只得到空对象。
3、如果obj里有函数,undefined,则序列化的结果会把函数, undefined丢失。
4、如果obj里有NaN、Infinity和-Infinity,则序列化的结果会变成null。
5、JSON.stringify()只能序列化对象的可枚举的自有属性。如果obj中的对象是有构造函数生成的, 则使用JSON.parse(JSON.stringify(obj))深拷贝后,会丢弃对象的constructor。
6、如果对象中存在循环引用的情况也无法正确实现深拷贝。

function Person (name) {
    this.name = 20
}

const lili = new Person('lili')

let a = {
    data0: '1',
    date1: [new Date('2020-03-01'), new Date('2020-03-05')],
    data2: new RegExp('\\w+'),
    data3: new Error('1'),
    data4: undefined,
    data5: function () {
        console.log(1)
    },
    data6: NaN,
    data7: lili
}

let b = JSON.parse(JSON.stringify(a))

 深拷贝方法二:

使用jquery中$.extend 用法: $.extend(true,{},obj)

       
        var obj = {a:1,b:2,c:3};
        var newObj = $.extend(true,{},obj);
        newObj.a = 10;
        console.log(obj);//{a: 1, b: 2, c: 3}
        console.log(newObj);//{a: 10, b: 2, c: 3}

深拷贝方法三: 递归方法


     function copy(obj) {
         let newObj = null; // 声明一个对象来存储拷贝之后的内容

      // 判断数据类型是否是复杂的数据类型,如果是则调用自己,如果不是则直接赋值即可!
      // 由于null不可以循环但是他的类型又是object,所以这个需要对null进行判断
      if (typeof (obj) == 'object' && obj !== null) {
        // 声明一个变量用以存储拷贝出来的值,根据参数的具体数据类型声明不同的类型来存储
        newObj = obj instanceof Array ? [] : {};
        // 循环obj的每一项,如果里面还有复杂的数据类型的话,则直接利用递归函数再次调用。
        for (let i in obj) {
          newObj[i] = copy(obj[i])
        }
      } else {
        newObj = obj
      }
      return newObj; // 函数没有返回的值的话,则为undefined
    }
    let obj = { name: "test", date:{c:4,d:2}}

    let obj1 = copy(obj);
    obj1.name = '张三';
    obj1.date.c = 40;
    console.log(obj, obj1);//name: "test", date:{c:4,d:2},name: "张三", date:{c:40,d:2}

浅拷贝方法一:

    var obj = {name:"张三",age:19,sex:"男"}
    var newObj = obj;

    newObj.name="李四";
    console.log(obj);//{name:"李四",age:19,sex:"男"}
    console.log(newObj);//{name:"李四",age:19,sex:"男"}

浅拷贝方法二:jquery中$.extend({},obj)

        
        var obj = {data:{a:1,b:2,c:3}};
        var newObj = $.extend({},obj);
        newObj.data.a = 10;
        console.log(obj);//{a: 10, b: 2, c: 3}
        console.log(newObj);//{a: 10, b: 2, c: 3}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值