{singhi}
🏷 tech
深度拷贝
🌙 💬 📅

支持基础类型数据、数组、对象、日期的拷贝,不支持函数拷贝,也不支持原型拷贝。

代码如下:

function clone(to, from) {
    if (isEqual(to, from)) return // Primary value includes Date.
    if (isArray(from)) cloneArray(to, from) // Array
    else cloneObj(to, from) // Object
}

function cloneObj(to, from) {
    Object.keys(from).forEach(key => {
        const value = from[key]
        const newVal = alloc(value)
        to[key] = newVal
        clone(newVal, value)
    })
}

function cloneArray(to, from) {
    from.forEach(value => {
        const newVal = alloc(value)
        to.push(newVal)
        clone(newVal, value)
    })
}

function isCloneable(from) {
    return !(from === null || 'number,boolean,bigint,string,function,undefined,'.indexOf(typeof from) > -1)
}

function isDate(from) {
    return from instanceof Date
}

function isArray(from) {
    return Array.isArray(from)
}

function isEqual(val, newVal) {
    return val === newVal || val - newVal === 0
}

function alloc(value) {
    if (isCloneable(value)) {
        if (isArray(value)) return []
        else if (isDate(value)) return new Date(value)
        else return {} 
    } else {
        return value
    }
}

使用场景一:拷贝数组

const to = []
const from = [
    {
        name: 'Singhi'
    },
    90,
    'Singhi',
    function() {
       console.log('func') 
    }
]

clone(to, from)

console.log(to)

这将输出:

[ { name: 'Singhi' }, 90, 'Singhi', [Function] ]

使用场景二:拷贝对象

const to = {}
const from = {
    name: 'Singhi',
    age: 30,
    address: ['China', 'Hubei', 'Huanggang', 'Xishui', 'Bahe', 'Luhua', { doorNo: 13490 }],
    say() {
        console.log('say')
    },
    birth: new Date(1989, 1, 8),
    note: null
}

clone(to, from)

console.log(to)

这将输出:

{ name: 'Singhi',
  age: 30,
  address:
   [ 'China',
     'Hubei',
     'Huanggang',
     'Xishui',
     'Bahe',
     'Luhua',
     { doorNo: 13490 } ],
  say: [Function: say],
  birth: 1989-02-07T16:00:00.000Z,
  note: null }

错误的调用

const to = [] // or value is not an object
const from = { name: 'Singhi' }
clone(to, from)

const to = { } // or value is not an array
const from = [ { name: 'Singhi' } ]
clone(to, from)

const to = { }
const from = new Date() // or other primary value.
clone(to, from)