js的浅拷贝与深拷贝的理解?

时间:2021-03-18 19:49:48

  拷贝的意思:顾名思义,就是copy的意思。

什么是浅拷贝? 什么是深拷贝?

 浅拷贝我理解为子对象寻找负对象的内存地址进行复制,如果子对象进行改变,这个内存地址是只有一个的,子对象进行改变时其实是改变了父对象中的属性,所以浅拷贝在子对象发生改变的时候父对象也会随着改变。

来看下这段代码:var a = [1,2,3];

var b =a ; var test = {name:'ningmeng', age:16}; var c = test; console.log(a);//[1,2,3] console.log(b);//[1,2,3] console.log(test);//{name:'ningmeng',age:'16'}
b[0] =5; c.age = 17; console.log(a);//[5,2,3] console.log(b);//[5,2,3] console.log(test);
//{name:'ningmeng',age:'17'}
console.log(c);
//{name:'ningmeng',age:'17'}
 
b指向a的内存地址,所以b在改变的时候a也发生了变化。
c指向test的内存地址,所以c在改变的时候test也发生了变化。

 深拷贝我理解为子对象在内存中开辟了一段新的空间,子对象复制了父对象的属性到自己的内存空间,因此子对象在改变的时候只是改变了自己内存空间的属性,而父对象内存空间中的属性不会发生改变,所以深拷贝在子对象发生改变的时候不会影响到父对象。

  大家都知道js中的对象比较复杂,所以我们先来看一下深拷贝中会遇到的问题

  来看一下这段代码:

              var deepArry = [];

              function deepCopy(arry1, arry2){

                       for(var i = 0,l= arry1.length;i<l;i++){ arry2[i] = arry1[i]; }

                        }

                var b = [[1,2,3],4,5];

                deepCopy(b,deepArry);

                console.log(b);

                console.log(deepArry);

                deepArry[0][1] =5;

                 console.log(b);

                 console.log(deepArry);

   js的浅拷贝与深拷贝的理解?

            你会发现一旦数组变为了多维数组,就不能达到自己预期的结果,我们来做一下优化:

           

  function deepCopy1(arry1, arry2) {
  for(var i = 0, l = arry1.length; i < l; i++) {
  //创建副本对象
  var tempArry = [];
  //判断数组
  if(arry1[i] instanceof Array) {
  deepCopy1(arry1[i], tempArry)
  arry2[i] = tempArry;
   } else {
  arry2[i] = arry1[i];
  }
  }
  }
  var b = [
  [1, 2, 3], 4, 5
  ];
  var c = [
  [1, [2, 3]], 4, 5
  ];
  var d = [
  [1, 2, 3], 4, [5, 6, 7]
  ];
  var deepArry = [];

  deepCopy1(b, deepArry);
  console.log(deepArry); //输出[[1,2,3],4,5]
  deepArry[0][0] = 9; //修改deepArry的值
  console.log(b); //输出[[1,2,3],4,5];
  console.log(deepArry); //输出[[9,2,3],4,5];

  deepArry.length = 0; //初始化deepArray
  deepCopy1(d, deepArry);
  console.log(deepArry); //输出[[1,2,3],4,[5,6,7]]

  deepArry.length = 0;
  deepCopy1(c, deepArry);
  console.log(c);       //[[1,[2,3]],4,5];
  console.log(deepArry);   //[[1,[2,3]],4,5];
  deepArry[0][1][0] = 99;
  console.log(c);       //[[1,[2,3]],4,5];
  console.log(deepArry);   //[[1,[99,3]],4,5];

  咦,你发现现在你已经完成了深拷贝,这是对于数组的深拷贝,但是如果是一个对象那?

  上代码:

  js的浅拷贝与深拷贝的理解?

         js的浅拷贝与深拷贝的理解?

 

 

   在这段代码执行完成之后,你会发现在hasOwnProperty属性未过滤掉原型链上得属性的时候,原型链的一直到最顶部都会被GET到,限制了之后就只有父级的原型链属性会被复制。而像js中的slice()函数和concat()函数也可以做到是深拷贝。希望小小的文章可以解决掉伙伴们的困惑。