学习完怕忘,记个笔记
JSON.parse(JSON.stringify())做深拷贝有哪些问题?
NaN
、Infinity
变为null
function
、symbol
、undefined
属性丢失- RegExp对象变为
空对象
- Date对象变为
字符串
- enumerable为false的不可遍历属性丢失
自己实现深拷贝
const isComplexDataType = obj => (typeof obj === 'object' || typeof obj === 'function') && obj !== null
const getAllKey = obj => [...Object.getOwnPropertyNames(obj), ...Object.getOwnPropertySymbols(obj)]
function deepClone ( source, hash = new WeakMap() ) {
//基础类型
if (!isComplexDataType(source)) {
return source
}
// Date类型
if (source instanceof Date) {
return new Date(source)
}
// RegExp类型
if (source instanceof RegExp) {
return new RegExp(source)
}
// function
if (typeof source === 'function') {
return new Function(`return ${source}`)()
}
// 判断循环引用
if (hash.has(source)) return hash.get(source)
// 复制不可遍历属性
const allDes = Object.getOwnPropertyDescriptors(source)
// 处理原型属性
const targetObj = Object.create(Object.getPrototypeOf(source), allDes)
const keys = getAllKey(source)
hash.set(source, targetObj)
// 递归
for( let key of keys ) {
targetObj[key] = isComplexDataType(source[key]) ? deepClone(source[key], hash) : source[key]
}
return targetObj
}