day34-deepClone

拷贝

探究一下深拷贝,本文主要是浅拷贝、深拷贝的简单实现,并对循环引用就行一些了解。


准备

let data = {
id: '1',
segment: {
hitinfos: {
// 浅拷贝时rule为rule: [Object]
rule: {
a: 'no-placeholder',
b: 'no-tag'
},
level: 4
},
atoms: [
{ tgt: 'you dont know', src: '你不知道' },
{ id: 1, tgt: 'what', src: '什么' }
]
},
arr: [{
id: 1,
arr: 'arr1'
}],
value_1: undefined,
value_2: null,
value_3: true
}

浅拷贝

  • 简单的对象浅拷贝(只遍历一层)-拷贝引用
function cloneShadow(src) {
let tgt = {}
// 为什么不直接用“=”赋值
for (let prop in src) {
// 或者用if (Object.hasOwnProperty(prop)) {
if (Object.prototype.hasOwnProperty.call(src, prop)) {
tgt[prop] = src[prop]
}
}
return tgt
}
let test = cloneShadow(data)
data.id = 2
console.log(test)
console.log(data)
console.log(test)

深拷贝

  • 递归对象深拷贝(遍历多层)
    function deepClone(src) {
    // 非对象
    if (src && typeof src !== 'object') {
    return src
    // throw new TypeError('Except Object, got' + (typeof src))
    }
    // 初始化
    let tgt = Array.isArray(src) ? [] : {}
    for (let prop in src) {
    if (Object.prototype.hasOwnProperty.call(src, prop)) {
    // value为null或者undefined则返回原值(typeof null === 'object')
    if (typeof src[prop] === 'object') {
    tgt[prop] = deepClone(src[prop])
    } else {
    tgt[prop] = src[prop]
    }
    }
    }
    return tgt
    }
    let test_1 = deepClone(data)
    console.log(test_1)
    console.log(data)
    console.log(test_1)

拷贝循环引用

  • 拷贝循环引用(JSON方法抛异常)
    function deepCloneCircle(src) {
    if (src && src !== 'object') return src
    let tgt = Array.isArray(src) ? [] : {}
    for (let prop in src) {
    if (Object.prototype.hasOwnProperty.call(src, tgt)) {
    if (src[prop] && src[prop] === 'object') {
    tgt[prop] = deepCloneCircle(src[prop])
    } else {
    tgt[prop] = src[prop]
    }
    }
    }
    return tgt
    }
    let test = deepCloneCircle(data)
    console.log(test)

参考:

[1]. JavaScript中的浅拷贝和深拷贝
[2]. 【进阶4-3期】面试题之如何实现一个深拷贝

文章作者: lmislm
文章链接: http://lmislm.com/2019/02/13/2019-02-13/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 LMISLMのBlog