深拷贝和浅拷贝

142 阅读1分钟

前言

出差很久,终于回来了并且有时间更新了。。
刚开始学习前端的时候,我以为浅拷贝类似下面这种

      let obj = {
        name: "123",
      };
      let a = obj;
      a.name='asd'

此时打印obj,发现obj.name=asd,而深拷贝则是改变a.name 但是obj.name并不会随之改变
后来才发现这种似乎不太准确,

深拷贝和浅拷贝只存在于复杂场景中,即对象的属性还是对象。

浅拷贝

只复制一层,当对象的属性为对象时,只复制其引用,当引用值发生变化时,也会跟着发生变化

首先定义两个数组和对象

      let arr = [1, 2, [3, 4]];
      let obj = {
        a: 1,
        b: { c: 2 },
      };
      let arr1 = [];
      let obj1 = {};

浅拷贝方法1 :遍历

先看数组

      for (let i = 0; i < arr.length; i++) {
        arr1.push(arr[i]);
      }
      arr1[0]=0
      arr1[2][0] = 0;
      console.log(arr1, arr);

结果如下图 再来看对象

      for (const key in obj) {
        obj1[key] = obj[key];
      }
      obj1['a']=2
      obj1['b']['c']=3
      console.log(obj1,obj);

可以看出浅拷贝确实如上所述 当然还有很多浅拷贝方法,例如Object.assign,扩展运算符,concat ,slice等等

深拷贝

深拷贝就是当对象的属性也是对象的时候,改变其引用值,不会原对象不会更着变化

json.parse(JSON.stringify())

最常见的应该就是json.parse(JSON.stringify()) 但是这个方法无法复制函数和undefined

      let a = {
        name: undefined,
        age() {},
      };
      copyObj = JSON.parse(JSON.stringify(a));
      console.log(copyObj);  //copyObj={}

递归

      let test = {
        name: "tom",
        age: undefined,
        dirve: () => {},
        info: {
          height: 180,
        },
      };
      let deepClone = function (obj) {
        let newObj=Array.isArray(obj)?[]:{}
        for (const key in obj) {
          if (obj.hasOwnProperty(key)) {
            if(obj[key]&& typeof obj[key]==='object'){
              newObj[key]=deepClone(obj[key])
            }else{
              newObj[key]=obj[key]
            }
          }
        }
        return newObj
      };
      let copyObj=deepClone(test)
      copyObj.name='jerry'
      copyObj.info.height=170
      console.log(test,copyObj)

上述的深拷贝和浅拷贝好像都有各种解释的方法,其实我也不确定哪一种是正儿八经的,我记得我之前看js高程的时候,好像有过我写的这一段解释,但是写这个文章的时候,却找不到了,可能我记忆出现了偏差 如果又更好的方法或者错误,希望有大佬指导一哈