JS中的深浅拷贝
为什么要进行拷贝
首先我们知道JS中的数据类型分为基本类型和引用类型:
- 基本类型:Number, Stirng, Boolean, Null, Undefined :(赋值)
- 引用类型:Object :(赋址)
其中基本类型存放在内存栈中,而引用类型存放在内存堆中。因此在对基本类型进行复制时,(var i = 0; var j = i
),将会重新开辟一个新的内存存放该基本类型,新旧数据互不干扰。而引用类型的变量其实更像一个指针(个人理解),因此在对新的变量赋值时,其实只是将地址赋值给这个变量,所以新旧变量其实指向的是同一数据,当对其中一个对象进行操作时,会影响到另一个变量。
1 | var obj1 = { |
浅拷贝
拷贝的是地址,最终两个变量指向同一份数据,修改其中一个变量会改变另一个。
使用原生的 Object.assgin()
就可以进行第一级属性的深拷贝(但并不是深拷贝)
1 | var obj1 = { |
而如果拷贝的对象当中包含对象(即拷贝对象为多级属性),那么 Object.assign()
方法只会拷贝对象的引用地址。
1 | var obj1={ |
深拷贝
两个变量是独立的,互不影响。
JSON.parse(JSON.stringify(object))
1 | var a = { |
缺点:
- 会忽略
undefined
- 会忽略
symbol
- 不能序列化函数
- 不能解决循环引用的对象
- 不能正确处理
new Date()
- 不能处理正则
递归实现
- 参数类型做校验,如果不是对象则直接返回
- 初始化新属性 对象|数组
- 对值为对象的属性继续深入拷贝/递归
1 | function deepCopy(source){ |