浅拷贝
: 当对于一个对象进行浅拷贝的时候,会创建一个新的对象,新对象包含有旧对象的所有属性,当属性值为基本类型时,拷贝的就是这个基本类型的值,当属性值为引用类型的时候,拷贝的是这个引用类型的内存地址深拷贝
:将一个对象从内存中完整的拷贝出来,开辟一个新的区域存储新对象,并且修改新对象不会影响旧对象实现深拷贝
- 使用
JSON.parse(JSON.stringify())
这种最简单的实现深拷贝的方法同时存在许多的缺点使用这种方法进行深拷贝的时候,对于上面一些特殊的属性值,会出现拷贝异常的情况:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
let obj = {
date: new Date(),
nan: NaN,
function: new Function(),
undefined: undefined,
regexp: new RegExp('\\w+'),
symbol: Symbol('symbol')
}
function deepClone(obj) {
return JSON.parse(JSON.stringify(obj))
}
let cloneObj = deepClone(obj)
console.log(cloneObj)
// 打印结果如下
{ date: '2021-02-26T07:22:37.173Z', nan: null, regexp: {} }undefined
,symbol
,函数
会被忽略掉NaN
会被转换为null
regexp
会被转换为 空对象date
对象会被转换为日期字符串
- 一种
cloneDeep
的方法:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16function cloneDeep(value) {
if(typeof value === 'object' && value !== null) {
const isArray = Array.isArray(value)
let result = isArray ? [] : {}
if (isArray) {
value.forEach(val => {
result.push(cloneDeep(val))
})
} else {
for (let k in value) {
result[k] = cloneDeep(value[k])
}
}
return result
} else return value
}
lodash
中的 cloneDeep
方法
入口
1 | import baseClone from './.internal/baseClone.js' |
baseClone
文件中的 baseClone
方法,向这个方法中传入了两个数据:value
: 要进行复制的数据CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG
: 掩码,表明使用 baseClone
来进行深拷贝以及 symbol
数据类型的拷贝baseClone
1 | /** |
getTag
getTag
方法用来获取元素的类型1 | const toString = Object.prototype.toString |
initCloneObject
initCloneObject
用来初始化克隆对象:1 | // object 用来初始化克隆的对象 |
isPrototype
判断 value
是否为原型,如果是,返回 true
对于 原型
对象上面包含有 constructor
属性1 | const objectProto = Object.prototype |
1 | function isPrototype(vlaue) { |
false
, isPrototype
返回的结果为 true
, 与结果不符合,因此设置 一个 objectProto 来防止这种情况