一.深浅拷贝
...简单数据类型复杂数据类型
浅拷贝全部拷贝只拷贝第一层
深拷贝全部拷贝全部拷贝
二.刨根问底 为什么会出现深浅拷贝?
1.js数据底层存储原理
(1)基本数据类型: Number String Boolean Null Undifined
(2)复杂数据类型(包括但不限于): Object Array Function RegExp Map
(3)栈存储: 存放简单数据类型的值和复杂数据类型在堆中的地址,存取顺序先进后出
(4)堆存储: 存放复杂数据类型的值;随机存,直接取
2.为什么在内存中:简单数据类型存放和复杂数据类型地址在栈中,复杂数据变量在堆中 这样存储?
(1)首先是堆比栈要大,但是栈比堆的运算速度要快。 (2)将复杂数据类型放在堆中的目的是为了不影响栈的效率,而是通过引用的方式去堆中查找。 (3)简单数据类型比较稳定,并且它只占据很小的内存,将它放在空间小、运算速度快的栈中,能够提高效率。
三.刨根问底 底层是如何拷贝的?
下图告诉你:
let a = {
name: '张三',
children: {
name: '大儿子',
age: '18',
eat: function () {
console.log('大儿子:会吃')
},
sex: undefined,
RegExp: /^[a-z0-9_-]{3,16}$/,
},
eat: function () {
console.log('张三:会吃')
},
sex: undefined,
RegExp: /^[a-z0-9_-]{3,16}$/,
}
let b={}
1.浅拷贝a,执行
b=a;
b在栈中申请空间,但是指向的是a在堆中地址,a变,则b变。
3.不完全的深拷贝a,执行
let b = Object.assign({}, a)
b的第一级,在堆中重新申请内存,但是二级三级还指向a的,不完全拷贝。
3.深拷贝a,执行
let b =lodash.deepClone(a)
b和a完全独立,b拷贝了a的所有层级,b不指向a的堆地址,而是对所有层级重新申请新的堆空间,存放自己得值。
四.什么开发场景下需要深拷贝?
1.我认知内的深拷贝开发场景
(1)如果拷贝一个级联地址,数据结构有三级:省市区,当我们进行数据拷贝的时候,浅拷贝只能拷贝第一级,并且如果拷贝数据值变了会影响到被拷贝值的值,那就会出现数据不一致。
比如:我的原数据A是:河北省 邯郸市 大名县,后来把A的值给B,那现在B的值就是:河北省邯郸市大名县,这个时候,改变A的值,A改成了:浙江省杭州市余杭区,那B的值会变成:浙江省邯郸市大名县,这个地址就错了,所以必须使用深拷贝。
综上所述:当拷贝变量是多层级的数据时,拷贝最好还是使用深拷贝。否则可能会导致数据错误。
五.实现深拷贝的几种常用方法及优缺点
1.不完全的深拷贝方式
(1)object.assign(a,b):
assign的用法
优点:可以拷贝函数;可以拷贝正则,可以拷贝undifined;
缺点:二级及以下不可以进行深拷贝。
(2)JSON.parse(JSON.stringify(a))
原理:将 JS 值转换为 JSON 字符串,然后将数据转换为 JS对象,相当于重新生成一个变量
JSON.stringify用法
JSON.parse用法
缺点:无法拷贝函数、正则、undifined。
优点:可以实现拷贝二级。
1.完全的深拷贝方式
(1)lodash递归
优点:可以实现完全拷贝且独立。
使用方法:
npm i --save lodash
import * as _ from 'lodash'
lodash.deepClone() // 深拷贝,完全
lodash使用方法
3.demo
let a = {
name: '张三',
children: {
name: '大儿子',
age: '18',
eat: function () {
console.log('大儿子:会吃')
},
sex: undefined,
RegExp: /^[a-z0-9_-]{3,16}$/,
},
eat: function () {
console.log('张三:会吃')
},
sex: undefined,
RegExp: /^[a-z0-9_-]{3,16}$/,
}
// let b = a // 赋值
// let b = Object.assign({}, a) // 浅拷贝
// let b = JSON.parse(JSON.stringify(a)) // 深拷贝, 不完全
// lodash.deepClone() // 深拷贝,完全
a.name = '张四'
a.children.age = 100
console.log('a', a)
console.log('b', b)
扩展
jsonStringify 内存问题,研究一下
递归思想/算法
内存泄漏, 闭包,
4. 节流 / 防抖
队列,数据列专题
Object.proxy()