zoukankan      html  css  js  c++  java
  • JavaScript中的深浅拷贝

    深浅拷贝

    在JS中,数据类型分为两类:

    简单数据类型:Number、Boolean、String、undefined

    引用数据类型:Array、Object、Function

    简单数据类型通常的操作为赋值,引用数据类型就是增删改插等操作了

    深浅拷贝就是对引用数据使用的。

    浅拷贝

    理解:存在一个“指针”指向某块内存,再增加一个“指针”指向该内存;如果这个内存发生改变,那么,新增指针也会发生改变。

    特点:无法切断数组内部引用数据类型的引用关系。

    代码分析:

    案例一:

    <script>
         var arr1 = [1,2,3,4,5]
         var arr2 = arr1;
        arr1.splice(2,3);  // 删除索引为2开始以后的3项(包括索引为2 的项)
        console.log(arr1); // [1, 2]
        console.log(arr2); // [1, 2]
    </script>

    这是一个简单的浅拷贝,首先声明一个arr1的数组,然后又声明arr2 的数组,并且把arr1赋给arr2,然后删除arr1 的项,arr2也跟着改变,这就是浅拷贝。

    案例二:

    var obj1 = {
      name: 'hf',
      age: 23,
      gender: '男',
      friends: {
           boy: 'zs',
           gril: {
           person1: 'ls',
             person2: 'ww'
         }
      },
      sayHi: function () {
          consoloe.log("我有三个朋友");
      }
    };
    var obj2 = {};
        for (var k in obj1) {
          obj2[k] = obj1[k];
     }
    delete obj1.friend.boy; //将obj1中的friends对象的boy键值对删除
    console.log(obj1);
    console.log(obj2); 

    可见,将obj1中的friends对象的boy键值对删除,obj2 中的对应项也会删除,这是为什么呢?

    解释一下:通过for in 来拷贝对象时,如果键值对就是普通的name:value时,那么就把内存拷贝一份(这是深拷贝);如果对象里面的某个键值对也是对象的话,那么就是增加一个新的指针,指向obj1的键值对象,没有开辟一份新的地址,依然指向原来的地址,不会像普通的键值对再复制一份,所以就发生以上删除obj1中的friends对象的boy键值对,obj2的对应项也会删除的情况!

    深拷贝

    深拷贝就是新增加一个“指针”,指向一块新开辟的内存,然后拷贝某个对象或数组,当释放这个对象或数组时,这个深拷贝的对象或数组不会随着释放掉。

    特点:彻底切断了数组内引用类型的引用关系。

      <script>
        // obj1 为将要拷贝的对象
        // obj2 为拷贝到的目标对象
        function deepCopy(obj1,obj2) {
          for (var k in obj1) {
            // 如果键值对不是object或者null类型的
            if (typeof obj1[k] != "object" || typeof obj1[k] === null) {
              obj2[k] = obj1[k]; // 基本数据进行浅拷贝
            } else {// 如果复杂数据类型值有可能是对象,也有可能是数组,需要进行判断后再设置
              obj2[k] = obj1[k] instanceof Array ? []:{};
              // 再把这个是数组或者是对象的“键值对”调用函数
              deepCopy(obj1[k],obj2[k]);
            }
          }
        }
        var obj1 = {
            name: 'hf',
            age: 23,
            gender: '男',
            friends: {
              boy: 'zs',
              gril: {
                person1: 'ls',
                person2: 'ww'
            }
            },
            sayHi: function () {
                consoloe.log("我有三个朋友");
            }
          };
          var obj2 = {};
          deepCopy(obj1,obj2);
          delete obj1.friends.boy; //将obj1中的friends对象的boy键值对删除,但是对obj2中的数据没哟影响
          console.log(obj1);
          console.log(obj2); 
      </script>

  • 相关阅读:
    NTP on FreeBSD 12.1
    Set proxy server on FreeBSD 12.1
    win32 disk imager使用后u盘容量恢复
    How to install Google Chrome Browser on Kali Linux
    Set NTP Service and timezone on Kali Linux
    Set static IP address and DNS on FreeBSD
    github博客标题显示不了可能是标题包含 特殊符号比如 : (冒号)
    server certificate verification failed. CAfile: none CRLfile: none
    删除文件和目录(彻底的)
    如何在Curl中使用Socks5代理
  • 原文地址:https://www.cnblogs.com/houfee/p/9148008.html
Copyright © 2011-2022 走看看