浅拷贝和深拷贝的区别?详细了解几种实现方式?

浅拷贝:只是申请增加一个指针,指向已存在的地址,同一个地址,其中一个改变另一个也会被改变。

深拷贝:是增加了一个指针,并且申请了一个新内存,使这个指针指向这个新内存,所以其中一个改变另一个也不会被改变。

1.浅拷贝

  const obj={
      a: 1,
      b: 'abc',
      c: {c1: 111},
      d: [1, 2, {d1:111}],
      e:new Set([{el:111}]),//object类型
    }
    //第一种实现浅拷贝方式扩展符号...
    const clone={...obj};
    console.log(clone);
    //第二种assgin()接收多个参数
    const clone2=Object.assign({},obj);
    console.log(clone2);
    //第三种利用key值,reduce循环遍历赋给一个新对象储存
    //前提是对象{}
    //=>括号是(接收对象{...res,[cur]:obj[cur]}),
    //...res物件,cur当前[cur]:obj[cur]是赋给新的对象
    const clone3=Object.keys(obj).reduce((res,cur)=>({...res,[cur]:obj[cur]}),{})
    console.log(clone3);
    //第四种for in循环
    const clone4={};
    for(let key in obj){
     clone4[key]=obj[key];
    }
    console.log(clone4);

实现效果图:
在这里插入图片描述
1.1基本数据类型和引用数据类型
基本数据类型:
number、string、boolean、null、undefined、symbol、
引用数据类型:
object(又分为:[],{}) 、function、

2.深拷贝:

//tostring得到值较准确,判断比较细致
//call调用一个对象,用另一个对象替换当前对象,可以传递多个参数
//prototype原型可以让所以的对象实例共享它所包含的属性和方法

function deepClone(obj){
     const type=Object.prototype.toString.call(obj);//类型
     switch(type){//switch case语句可以用于基于不同的条件来执行不同的动作
      case '[object Object]': {//object如果是对象的操作
        const  cloneObj = {};
        for(let key in obj){//for in去循环
         cloneObj[key] = deepClone(obj[key]);//cloneObj[key]=obj[key]这个是浅拷贝
         //cloneObj[key]=deepClone(obj[key])这个是深拷贝
        }
        return cloneObj;//返回值
      }
      case '[object Array]': {//map()方法去循环//如果是Array就用map去循环
        return obj.map(item => deepClone(item));
        //1.obj.map(item值=>返回所有itme),但不能确定是基本类型还是复杂类型
        //2.所以用deepClone(item)
        //3.直接return返回
      }
       case '[object Set]':{//考虑set类型
       const cloneObj=new Set();//new Set创建方式,一个set
       obj.forEach(item=>{//forEach循环obj
       //使用add()添加set
       cloneObj.add(deepClone(item))
       })
       return cloneObj;//返回
      }
      //否则:
      default:
         return obj;
     }
    }
    const cloneObj = deepClone(obj);

    obj.a=1234;
    console.log('a',obj.a,clone.a,cloneObj.a);
    
    obj.c.c1=1234;
    console.log('c.c1',obj.c.c1,clone.c.c1,cloneObj.c.c1);
    //clone.c.c1被影响浅拷贝  cloneObject.c.c1未被影响深拷贝
    
    obj.d[2].d1=1234;
    console.log('d[2].d1',obj.d[2].d1,clone.d[2].d1,cloneObj.d[2].d1);
   //clone.d[2].d1被影响浅拷贝  cloneObject.d[2].d1未被影响深拷贝
   
   obj.e.add(1234);//增加1234
   obj.e.values().next().value.e1=1234;
   //ES6中values是迭die代器
   //next()寻找下一项.value内容.找到e1
   console.log('e',obj.e,clone.e,cloneObj.e);
   //clone.e是浅拷贝e  cloneObj.e是深拷贝的e

实现效果
在这里插入图片描述

自己手动操作一下,可以加深记忆法,记录下我的经验。

猜你喜欢

转载自blog.csdn.net/weixin_46409887/article/details/111068701