js对象的直接赋值、浅拷贝与深拷贝

js对象的直接赋值、浅拷贝与深拷贝

最近做到一个用编程实现js对对象的深拷贝浅拷贝的问题,下面就来总结一下直接赋值,浅拷贝,深拷贝的差别,以及代码实现方式!!

直接赋值

把一个对象A赋值给一个对象B相当于把一个对象B的地址指向对象A地址,所以,他们实际上是同一个对象。以图1直接赋值的例子,person对象中有两个属性,一个是name,一个是对象属性address;为什么设置一个对象属性呢?下面会涉及到浅拷贝和深拷贝问题,这也是他们之间的区别。
严格相等运算符"==="来检测二者是否指向同一个地址
结论:
无论修改赋值后的对象B的非对象属性还是对象属性,都会影响原对象A的对应的属性
在这里插入图片描述

浅拷贝

修改赋值后的对象B的非对象属性,不会影响原对象A的非对象属性;修改赋值后的对象B的对象属性,却会影响原对象A的对象属性。

浅拷贝的2种方法(ES6语法):

  • Object.assign(target, sources)
  • 扩展运算符(…),例:var copy= { …person };
    在这里插入图片描述

在这里插入图片描述

深拷贝

深拷贝会另外拷贝一份一个一模一样的对象,但是不同的是会从堆内存中开辟一个新的区域存放新对象,新对象跟原对象不再共享内存,修改赋值后的对象b不会改到原对象a。即深拷贝,修改赋值后的对象b的非对象属性,不会影响原对象a的非对象属性;修改赋值后的对象b的对象属性,也不会影响原对象a的对象属性。而且,二者不指向同一个对象。

方法一:利用 JSON 对象中的 parse 和 stringify;

var obj1 = {
    name: "cat",
    show:function(){
        console.log(this.name);
    }
};
var obj2 = JSON.parse(JSON.stringify(obj1));

obj2.name = "pig";

console.log(obj1.name); //cat
console.log(obj2.name); //pig

obj1.show(); //cat
obj2.show();  //函数被丢失,报错

JSON.stringify()会导致一系列的问题,因为要严格遵守JSON序列化规则:原对象中如果含有Date对象,JSON.stringify()会将其变为字符串,之后并不会将其还原为日期对象。或是含有RegExp对象,JSON.stringify()会将其变为空对象,属性中含有NaN、Infinity和-Infinity,则序列化的结果会变成null,如果属性中有函数,undefined,symbol则经过JSON.stringify()序列化后的JSON字符串中这个键值对会消失,因为不支持。

方法二:利用递归来实现每一层都重新创建对象并赋值

 var obj1 = [{
     name:'cat',
     address:{city:'北京',area:'昌平',tel:[1,2,3]},
     show: function(){
       console.log(this.address.city+''+this.name);
     }
   }]
   var obj2={
     arr1:[1,{arr2:[1,5,7]}],
     message:'你好啊'
   }
   function deepClone(obj){
     //判断obj为object还是array,因为array也是object类型的,但是object不是array类型的
     //需要先行判断是否因为array类型
    let objClone = Array.isArray(obj)?[]:{};
    //obj存在,且obj类型为object(数组类型也为object)
    if(obj && typeof obj ==='object'){
      //遍历对象中的每个子元素
      for(key in obj){
        if(obj.hasOwnProperty(key)){
          //判断obj子元素是否为对象,如果是,递归复制
          if(obj[key] && typeof obj[key] ==='object'){
            objClone[key] = deepClone(obj[key]);
          }else{
            //如果不是,就简单复制就可以了
            objClone[key] = obj[key];
          }
        }
      }
    }
    return objClone;
   }
   console.log(typeof [1,2,2]); //object
   console.log(deepClone(obj1));
   console.log(deepClone(obj2));
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值