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>

  • 相关阅读:
    搭建高可用mongodb集群—— 副本集
    搭建高可用mongodb集群(一)——mongodb配置主从模式
    单线程异步回调机制的缺陷与node的解决方案
    js实现接口的几种方式
    访问者模式和php实现
    策略模式和php实现
    状态模式和php实现
    观察者模式和php实现
    C语言之一般树
    电子相册之bitmap
  • 原文地址:https://www.cnblogs.com/houfee/p/9148008.html
Copyright © 2011-2022 走看看