js 深浅拷贝的整理[亲测有效]

js 深浅拷贝的整理[亲测有效]好记性不如烂笔头。记在脑子里不如做点笔记。什么是深浅拷贝?在理解这个问题之前,我们要先去了解一下js的数据类型,js数据类型分为基本数据类型和引用数据类型。基本数据类型: string,number,null,undefined,boolean引用数据类型: object对象(array,function,date,reg)我们知道了js的数据类型,现在就可以来了解什么是深浅拷…

大家好,欢迎来到IT知识分享网。

好记性不如烂笔头。记在脑子里不如做点笔记。

什么是深浅拷贝?

在理解这个问题之前,我们要先去了解一下js的数据类型,js数据类型分为基本数据类型引用数据类型

基本数据类型:
		string,number,null,undefined,boolean
引用数据类型:
		object对象(array,function,date,reg)

IT知识分享网

我们知道了js的数据类型,现在就可以来了解什么是深浅拷贝,先看基本数据类型的拷贝,代码如下:

IT知识分享网var a = 2;  // 定义a变量赋值为2
var b = a;  // 把a变量赋值给b
a = 1;     // 修改a的值
console.log(a, b); // 1, 2 

由上可以看出,a的值改变之后,b的值并没有跟着改变,再来看看引用类型的拷贝,代码如下:

var a = [1, 2, 3, 4];
var b = a;
a[1] = 0;
console.log(a, b); 

结果:在这里插入图片描述
操作和基本数据类型一样,b会跟着a改变,为什么会出现这样的情况呢?因为基本数据类型保存在栈内存里,而引用数据类型保存在堆内存里,保存在栈内存的必须是大小固定的数据,引用类型的大小不固定,只能保存在堆内存中,而我们定义的变量实际保存的是一个指针,这个指针指向的是堆内存。
在这里插入图片描述
代码解析:
1.基本数据类型拷贝:
当var a = 2的时候在栈内存中新开辟了一个空间保存a变量值为2,进行var b = a的时候是在内存中又开辟了新的空间保存着b,所以a和b两个变量互不相关。
2.引用数据类型拷贝:
进行var a = [1,2,3,4]的时候,在栈内存中保存的只是一个指针也可以说是地址,这个指针指向的是堆内存的一个对象,堆内存中保存着这个对象,当var b = a的时候,我们进行了复制但是复制的只是栈内存中的指针,堆内存中的本身对象并没有被复制,所以a[1] = 0的时候,b也改变了,因为a和b指向的是同一个对象。这就是浅拷贝。

IT知识分享网由上总结得出:基本数据类型的拷贝就是直接赋值的操作,而深浅拷贝相对应的就是引用数据类型。

浅拷贝

浅拷贝只是拷贝基本类型的数据,如果所拷贝的对象的属性等于数组或另一个对象那就是只拷贝了指针,而没有拷贝堆内存中存储内容的对象,只要这个对象所改变了,所有指向这个对象的变量的值都会改变。看代码:戳这里

var Nation = { 
     
     nation: '中国'
};
function extendCopy(p) { 
     
	var c = { 
   };  
    for (var i in p) { 
       
         c[i] = p[i];  
    }  
    return c;
}
var Doctor = extendCopy(Nation);
Doctor.career = '医生';
Doctor.nation = '美国';
console.log(Doctor.nation); // 美国
console.log(Nation.nation); // 中国
console.log(Doctor.career); // 医生

好像看起来都没错,Doctor对象新增了career 属性,而Nation对象并没有career 属性,他们好像没有什么关联,如果我们给属性的值是一个对象呢?再来看看:

 // 封装一个浅拷贝函数:
  function simpleClone(initalObj) { 
       
     var obj = { 
   };    
     for ( var i in initalObj) { 
   
            obj[i] = initalObj[i];
     }    
     return obj;
 }
 // 定义一个多层次的对象
  var obj = { 
   
          a: "hello",
          b:{ 
   
              a: "world",
              b: 21
          },
          c:["Bob", "Tom", "Jenny"],
          d:function() { 
   
              alert("hello world");
          }
   }
   // 赋值obj对象
   var obj1 = simpleClone(obj);
   obj1.c = ['mm', "Tom", "Jenny"];   // 改变obj1中的c属性的值
   // 打印一下
   console.log('obj=>>>',obj);  //obj.c => ["Bob", "Tom", "Jenny"]
   console.log('obj1=>>>',obj1);  //obj.c => ["mm", "Tom", "Jenny"]
   // 再来改变数组中的第一个元素 把上面的赋值和打印注释一下
   obj1.c[0] = 'bb'; // 浅拷贝时,改变属性的属性值,改变原对象
   // 再打印一下
   console.log('obj=>>>',obj); //obj.c => ["bb", "Tom", "Jenny"]
   console.log('obj1=>>>',obj1);  //obj.c => ["bb", "Tom", "Jenny"]

哦豁 完蛋, obj1.c[0] = ‘bb’执行这一步的时候两个对象都改变了,为啥执行obj1.c = [‘mm’, “Tom”, “Jenny”]的时候两个对象没有关联,因为浅拷贝是只拷贝一层,把 obj1.c作为一个整体改变了,而obj1.c[0] = ‘bb’深层次的对象的改变就需要用到深拷贝了。
另外:Object.assign()也能实现浅拷贝

深拷贝

深拷贝的实现方式有很多种

  1. 最简单的json方法
    JSON.parse(JSON.stringify(obj))
  2. 使用Object.create()方法
function deepClone(initalObj, finalObj) { 
       
  var obj = finalObj || { 
   };    
  for (var i in initalObj) { 
           
    var prop = initalObj[i];        // 避免相互引用对象导致死循环,如initalObj.a = initalObj的情况
    if(prop === obj) { 
               
      continue;
    }        
    if (typeof prop === 'object') { 
   
      obj[i] = (prop.constructor === Array) ? [] : Object.create(prop);
    } else { 
   
      obj[i] = prop;
    }
  }    
  return obj;
}
  1. 递归
function deepClone(initalObj, finalObj) { 
       
  var obj = finalObj || { 
   };    
  for (var i in initalObj) { 
           
    var prop = initalObj[i];        // 避免相互引用对象导致死循环,如initalObj.a = initalObj的情况
    if(prop === obj) { 
               
      continue;
    }        
    if (typeof prop === 'object') { 
   
      obj[i] = (prop.constructor === Array) ? [] : { 
   };            
      arguments.callee(prop, obj[i]);
    } else { 
   
      obj[i] = prop;
    }
  }    
  return obj;
}
var str = { 
   };
var obj = { 
    a: { 
   a: "hello", b: 21} };
deepClone(obj, str);
console.log(str.a);

代码摘自:https://blog.csdn.net/weixin_37719279/article/details/81240658

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/11485.html

(0)

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

关注微信