深拷贝和浅拷贝
1.前言
基本数据类型:undefined,boolean,number,string,null,symbol(ES6)。 基本类型的名字和值都存放在栈区,访问是按值访问的,就是说你可以操作保存在变量中的实际的值。见下图
当然,let a=1,b=a;虽然b不受a影响,但这也算不上深拷贝,因为深拷贝本身只针对较为复杂的object类型数据。
引用数据类型:是指Object ,Function,Array。可以拥有属性和方法,并且我们可以修改其属性和方法。引用对象存放的方式是:在栈中存放对象变量标示名称和该对象在堆中的存放地址,在堆中存放数据。
注意:对象使用的是引用赋值。当我们把一个对象赋值给一个新的变量时,赋的其实是该对象的在堆中的地址,而不是堆中的数据。也就是两个对象指向的是同一个存储空间,无论哪个对象发生改变,其实都是改变的存储空间的内容,因此,两个对象是联动的。
深拷贝:复制并创建一个一模一样的对象,不共享内存,修改新对象旧对象不会变。
浅拷贝:只复制指向某个对象的指针,而不复制这个对象本身,新旧对象共享一块内存。
2.实现深拷贝的方式
注意:第一层的属性确实深拷贝,拥有了独立的内存,但更深的属性却仍然公用了地址,所以才会造成上面的问题。同理,concat方法与slice也存在这样的情况,他们都不是真正的深拷贝,这里需要注意。
(1)递归去复制所有层级属性。
(2)利用json对象的parse和stringify。
JSON.stringify()的作用是将 JavaScript 对象转换为 JSON 字符串,而JSON.parse()可以将JSON字符串转为一个对象。
JSON.parse()需要注意一点----由于此方法是将JSON字符串转换成对象,所以你的字符串必须符合JSON格式,即键值都必须使用双引号包裹:
(3)JQ的extend方法。
拓展1:JSON.stringify()的几种妙用。
1.对象的深拷贝,见上面。
2.判断数组是否包含某个对象,或者判断对象是否相等。
3.让localStorage/sessionStorage可以存储对象。
localStorage/sessionStorage默认只能存储字符串,而实际开发中,我们往往需要存储的数据多为对象类型,那么这里我们就可以在存储时利用json.stringify()将对象转为字符串,而在取缓存时,只需配合json.parse()转回对象即可。
拓展2:JSON.stringify()与toString()的区别
let arr = [1,2,3]; JSON.stringify(arr);//'[1,2,3]' arr.toString();//1,2,3
其次,JSON.stringify()的受众更多是对象,而toString()虽然可以将数组转为字符串,但并不能对{name:'天子笑'}这类对象实现你想要的操作,它的受众更多是数字。
本文来自博客园,作者:122www,转载请注明原文链接:https://www.cnblogs.com/131362wsc/p/17099517.html