nfssuzukaze / Blog

0 stars 0 forks source link

深浅克隆的简易实现 #30

Open nfssuzukaze opened 3 years ago

nfssuzukaze commented 3 years ago

浅克隆的实现

const clone = (value) => {
    if (value === null || typeof value !== "object") return
    // 若要克隆的不是对象, 则直接返回

    const newQuote = value instanceof Array ? [] : {}

    for (let key in value) {
        if (value.hasOwnProperty(key)) 
            newQuote[key] = value[key]
    }

    return newQuote
}

深克隆的初步实现

克隆对象, 数组, 函数

const deepClone = (value) => {
    if (value === null || typeof value !== "object") return
    // 若要克隆的 value 不是对象, 则直接返回
    const newQuote = value instanceof Array ? [] : {}

    for (let key in value) {
        if (value.hasOwnProperty(key)) 
            newQuote[key] = (typeof value[key] === "object" && value[key] !== null) ? deepClone(value[key]) : value[key]
            // 在 value[key] 是对象自身属性的前提下, 是对象的话, 则进行递归克隆, 否则直接将其值赋给新对象
    }

    return newQuote
}

深克隆的进一步实现

解决了因为 let a = {}, a.a = a 这种情况而导致的爆栈问题

const deepClone = (value) => {
    const _set = new Set()

    const _deepClone = (value) => {
        if (value === null || typeof value !== "object") return 
        // 如果不是对象, 则直接返回
        if (_set.has(value)) return value
        // 如果有循环嵌套, 如 let a = {}, a.a = a 这样的情况, 则第二次遇到时直接返回, 不再向下递归
        _set.add(value)
        // 每遇到一个新 value 都会放入 _map 中

        const newQuote = value instanceof Array ? [] : {}

        for (let key in value) {
            if (value.hasOwnProperty(key)) 
                newQuote[key] = (typeof value[key] === "object" && value[key] !== null) ? _deepClone(value[key]) : value[key]
        }

        return newQuote
    }

    return _deepClone(value)
}