辨析浅拷贝与深拷贝

浅拷贝:浅拷贝是把一个对象内容或地址给另一个对象,他们指向相同,两对象有共同属性和方法(一块内存中内容赋值一份给另一块内存)。

深拷贝:深拷贝是把一个对象中的属性和方法找到,在另一个对象中开辟相应的空间,一个个存储在另一个对象中。

*深拷贝与浅拷贝的区别?

浅拷贝:指向的是同一块内存地址,当一个发生变化时另一个也跟着变;

深拷贝:在计算机中开辟出一块新的内存地址用于存放复制的对象;

 

实现:

浅拷贝:

(1)对象中:

  Object.assign()

let a = {

  name: 'zhangsan',

};

 

let b = Object.assign({},a);

a.name = 'wangwu';

console.log('a==', a, 'b===', b);

//a== {name: "wangwu"} b=== {name: "zhangsan"}

 

扩展运算符

 

let a = {

  name: 'zhangsan',

};

let c = { ...a };

a.name = 'wangwu';

console.log(c);//{name: "zhangsan"}

 

(2)数组中:

数组有两个方法 concat 和 slice 是可以实现对原数组的拷贝的,这两个方法都不会修改原数组,而是返回一个修改后的新数组。(浅拷贝,即都只对数组的第一层进行深拷贝)

 

注意:浅拷贝只解决了第一层的问题,如果对象中还有嵌套对象就需要使用深拷贝。

 

 

深拷贝:

JSON.parse(JSON.stringify(object))

 

let obj = {

  name: 'yangyi',

  age: 23,

  likes: {

    type: 1,

    width: 200,

    height: 300,

  },

};

 

let objs = JSON.parse(JSON.stringify(obj));

obj.likes.type = 2;

console.log('obj===', obj, 'objs==', objs);

//obj.likes.type=2,objs.likes.type=1

注意:该方法也是有局限性的(由于它是依赖于JSON,而JSON只支持object,array,string,number,true,false,null这几种数据或者值,其他的比如函数,undefined,Date,RegExp等数据类型都不支持。对于它不支持的数据都会直接忽略该属性。)

  • 会忽略undefined
  • 不能序列化函数
  • 不能解决循环引起的对象
  • 不能拷贝正则表达式
  • Date类型数据会被转化为字符串类型(丢失Date的一些特性,比如时间格式化等方法)

实现一个完整的深拷贝:

deepCopy = (target) => {
    if (typeof target !== 'object') return;
    let dist={};
    if(target instanceof Array){
      // 拷贝数组
      dist = [];
    }else if(target instanceof Function){
      // 拷贝函数
      dist = function () {
        return target.call(this, ...arguments);
      };
    }else if(target instanceof RegExp){
      // 拷贝正则表达式
     dist = new RegExp(target.source,target.flags);
    }else if(target instanceof Date){
        dist = new Date(target);
    }else{
      // 拷贝普通对象
      dist = {};
    }

   for(let key in target){
     if(target.hasOwnProperty(key)){
      dist[key]=typeof target[key]==='object'?this.deepCopy(target[key]):target[key];
     }
   }

    return dist;
  };

  

posted @ 2021-03-04 15:22  任雨前行  阅读(60)  评论(0编辑  收藏  举报