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>

原文地址:https://www.cnblogs.com/houfee/p/9148008.html