JSON.parse(JSON.stringify())做深拷贝有哪些问题?

688

学习完怕忘,记个笔记

JSON.parse(JSON.stringify())做深拷贝有哪些问题?

  • NaNInfinity变为null
  • functionsymbolundefined属性丢失
  • 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
}