JavaScript当中的浅拷贝和深拷贝
基本数据类型的赋值,当修改其中一个变量的数据的时候,另一个变量不受其影响。 --------------传值
但是当数据类型是引用数据类型的时候,通过变量赋值得到引用(堆栈问题),这时修改其中一个数据的时候,另一个变量也会同时更改。 --------------传址
但往往这种修改在实际开发中是不期望的。
因此JavaScript当中的深拷贝和浅拷贝在实际开发应用当中较为常见。
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
概念描述:
浅拷贝(浅复制):
浅拷贝在引用数据类型当中实际上拷贝的是(栈)内存当中的地址。(存在修改影响现象。)
总结:浅拷贝仅仅拷贝了栈当中的数据。(基本数据类型数据和引用数据类型指针)
确实实现了复制,表现为栈。
浅拷贝的实现方式:
1、等号赋值。(类似浅拷贝,但不是真正意义上的浅拷贝。等号赋值相当于引用的是同一个堆内存,但是浅拷贝是新开堆内存,嵌套以及二维数组涉及引用元堆内存址问题)
2、Object.assign()
3、ES6中的展开符 var swtObjCopy = {...swtObj}
4、数组当中的浅复制 Array.prototype.slice [1,2,3,[1,2,3]],存在第一层第二层问题
5、数组中的concat()连接两个数组。
。。。。。。
具体使用方法:
var swtObj = { name: "swtObj", hobby:{
iphone:"iphone11Pro",
computer:"Mac",
game:"王者荣耀"
} } var swtObjCopy = Object.assign({},swtObj);
//打印 console.log(swtObjCopy)
{ // name: "swtObj", // hobby: {iphone: "iphone11Pro", computer: "Mac",game:"王者荣耀"} // }
swtObj.name = "swtObjCopy";
swtObj.hobby.game:"放弃游戏,前端不香吗"
//打印 console.log(swtObj)
{ // name: "swtObjCopy", // hobby: {iphone: "iphone11Pro", computer: "Mac",game:"放弃游戏,前端不香吗"} // }
//打印 console.log(swtObjCopy)
{ // name: "swtObj", // hobby: {iphone: "iphone11Pro", computer: "Mac",game:"放弃游戏,前端不香吗"} // }
由此可见Object.assign()复制的对象,仅仅实现了第一层的复制 。 ------因此为浅拷贝。
深拷贝(深复制):(真正意义上的copy)
深拷贝就是在拷贝数据的时候,将数据的所有引用结构都拷贝一份。
深拷贝不仅仅会拷贝基本数据类型还会拷贝引用数据类型。
深拷贝需要新开堆内存,花销较大。深拷贝后的对象之间不受影响,相互独立。
深拷贝方式:
1、利用JSON达到深复制。----JSON.parse(JSON.stringify())
需要注意的是:
JSON实现深复制某些情况下是不能被正确复制的
比如:忽略undefined,symbol对象,不能序列化函数,不能解决嵌套引用{a:1,{b:2}},不能处理正则表达式,
不能处理内置对象new Date()(因为实时变化,但是可以转为字符串解决)
2、真正意义上的深复制就是浅拷贝一层然后递归复制。
3、热门的函数库lodash,也有提供_.cloneDeep用来做深拷贝。
4、jquery 提供一个$.extend可以用来做深拷贝。
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------