JavaScript之深浅拷贝

164 阅读1分钟

深拷贝和浅拷贝都是针对的引用类型。

浅拷贝

浅拷贝就是只复制引用,而未复制真正的值。

深拷贝

目前实现深拷贝的方法主要是两种:

  1. 利用 JSON 对象中的 parse 和 stringify;
  2. 利用递归来实现每一层都重新创建对象并赋值。

JSON.parse(JSON.stringify(obj))

如果对象中含有一个函数时(很常见),就不能用这个方法进行深拷贝,因为 undefinedfunctionsymbol 会在转换过程中被忽略。

递归

对每一层的数据都实现一次 创建对象->对象赋值 的操作。

function isObject(obj) {
    return obj && typeof obj === 'object'
}
function deepClone(obj) {
    if (!isObject(obj)) return obj
    let targetObj = obj.constructor === Array ? [] : {}
    for (let key in obj) {
        if (obj.hasOwnProperty(key)) {
            if (obj[key] && typeof obj[key] === 'object') {
                targetObj[key] = obj[key].constructor === Array ? [] : {}
                targetObj[key] = deepClone(obj[key])
            } else {
                targetObj[key] = obj[key]
            }
        }
    }
}

JavaScript中的拷贝方法

concat、slice、Object.assign()、 ...展开符 都是首层浅拷贝。

总结

  1. 赋值运算符 = 实现的是浅拷贝,只拷贝对象的引用值;
  2. JavaScript 中数组和对象自带的拷贝方法都是“首层浅拷贝”;
  3. JSON.stringify 实现的是深拷贝,但是对目标对象有要求:非function, undefined,symbol;
  4. 若想真正意义上的深拷贝,用递归实现。