JavaScript的深浅拷贝
JavaScript的数据类型 JS中有7种数据类型:String、Number、Boolean、Null、Undefined、对象以及ES6新增的Symbol。 由于目前还未深入了解过Symbol,所以此次不讨论Symbol。 其中6种为基本类型(或叫做简单数据类型)和1种引用类型(复杂数据类型)。 基本类型 String Number Boolean Null Undefined 引用类型 对象 不同数据类型在内存中如何存储? 我们将内存分为栈(Stack)内存和堆(Heap)内存 基本类型以固定大小的空间存在与栈内存中,当基本类型发生值的拷贝时,目标变量会得到原始变量的值的副本。 let a = 1 let b = a //1 引用类型的值是对象,保存在堆内存中,引用类型的变量的值并不是值的本身,而是这个值在堆内存中的地址(也有说法为指针,不过我个人觉得地址容易理解)。当引用类型发生值的拷贝的时候,实际上目标变量得到的是原始变量的值的地址。 let obj1 = { name: "jack" } /* 此时{name: "jack"}这个对象存在于堆内存中,我们假设他的地址是218 */ let obj2 = obj1 //在这个赋值操作中,传递的其实是对象在内存中的地址 浅拷贝 let data = { name: "jack", age: 18, gender: "male" } let copyDate = data copyDate === data //true copyDate.name = "Tom" copyDate.name === data.name //true copyDate === data //true 上面这段代码就是一个浅拷贝的例子,由此可见,浅拷贝就是目标变量得到原始变量的值后, 不管是目标变量还是原是变量,只要值发生变化,那么两个变量都会收到影响。这一点从内存图中就可以看出,因为引用地址相同。 深拷贝 let a = 1 let b = a b = 2 a //1 变量b得到变量a的值,但变量b的值改变,不影响变量a,这就是深拷贝 存在的问题 & 解决方法 有些时候,我们需要深拷贝一个对象或者数组,但=操作符只能实现浅拷贝 对象的深拷贝 //最容易想到的方法:遍历原始对象 let obj = { name: "jack" } let copyObj = {} for(let key in obj){ copyObj[key] = obj[key] } obj === copyObj //false //使用JSON let a = {name: "alex"} let b = JSON.parse(JSON.stringify(a)) //ES6的方法 let source = { name: "Tom", age: 18 } let target = Object.assign({}, source) //Object.assign方法用于将原始对象的所有可枚举属性复制到目标对象上。 target === source //false 数组的深拷贝 ...