深拷贝和浅拷贝
1. 什么是深拷贝和浅拷贝
浅拷贝:对变量值和内存地址的复制,并只用于引用。
深拷贝:对变量值和内存地址的拷贝,拷贝一份创建新的内存地址。
2. 深拷贝和浅拷贝有什么区别
浅拷贝:假如B复制了A, B值改变,A值跟着变,A和B在栈堆只占用了一个内存
深拷贝:假如B复制了A, B值改变,A值不会跟着变,A和B在栈堆占用了两个内存
3. 深拷贝和浅拷贝可以解决什么问题
深拷贝:定义的值不会被修改,可以靠这一点,给每个值定义自己私有的地址,可区分多个看似相同的值
浅拷贝:不做解释
4. 深拷贝和浅拷贝使用场景
深拷贝:适用于定义a,将a赋值给b,不论b如何改变都不会影响a,
1.一个组件,在一个页面多次使用
2.Json是在静态js文件,在页面中将json引用,并修改,因浏览器有缓存,可导致json文件内的数据被修改,这时候需要用到深拷贝,得到最始数据
浅拷贝:适用于定义a,将a赋值给b,不论b如何改变a值都会随着改变,
1.不做解释
5. 深拷贝和浅拷贝使用方法有哪些
浅拷贝:1.Object.assign() (多层拷贝) 查看具体实例( 3.ES6扩展运算符 )
2.array.slice(start, end) 从数组中根据下标截返回取数组 (对第一级数组元素是对象或者数组等引用类型变量的数组) 查看具体实例(2. slice())
3.array.concat(array1, array2, ..., arrayN) 多个数组拼接返回一个数组 (对第一级数组元素是对象或者数组等引用类型变量的数组) 查看具体实例(3. concat())
4..直接遍历 ( 对第一级数组元素是对象或者数组等引用类型变量的数组) 查看具体实例(1.直接遍历)
深拷贝:1. for循环 递归 查看具体实例(2.手动写递归)
2. lodash插件中 cloneDeep方法 例如:_lodash.cloneDeep(data) 懒人必备 推荐
3. immutable插件 查看具体实例(immutable的作用)
4.Object.assign() (第一层拷贝) 查看具体实例(2.ES6的Object.assign)
5.JSON.parse(JSON.stringify(data)) (不支持function,RegExp 正则)缺点:在拷贝后,不管对象原来的构造函数是什么,都会变成Object,同时如果对象存在循环引用的情况也无法正确处理 查看具体实例(1.JSON.parse(JSON.stringify(XXXX)))
6.array.slice(start, end) (对于多级数组元素是基本类型变量(如number,String,boolean)的简单数组) 查看具体实例(2. slice())
7.array.concat(array1, array2, ..., arrayN) (对于一级数组元素是基本类型变量(如number,String,boolean)的简单数组) 查看具体实例(上面的三种方式都将失效)
6. 深拷贝和浅拷贝优缺点
浅拷贝:优点:与深拷贝相比不占用内存,不影响性能
缺点:因使用的同一个地址,B值改变,A值也会随着改变
深拷贝:优点:有自己独立属性,地址,不可被更改
缺点:与浅拷贝相比占用内存,并非常影响性能问题,不建议大范围的使用
7. 总结
对于深拷贝浅拷贝如果想搞明白的话,还需要搞懂 栈堆 是什么?为什么会拷贝的时候会将值存储在栈堆中。明白这个的话,拷贝这块就了解的差不多了,学习新的东西还是需要找关联最头部开始下手,一环扣一环学起来还是很快的
不理解的可查看下图