(未完成)在 JavaScript 中如何实现深拷贝?

As we know,在 JavaScript 中,对象是以引用的形式存储在一个变量中的,我们使用这样的变量进行赋值实际上复制的只是这个对象的引用,如果我们想真正完全地复制一个对象,这种操作就叫深拷贝

For Example

对于 number, string, boolean, null, undefined, symbol 这种东西来说,我们称之为原始值(这里就不用纠结 typeof null === 'object' 了,非本文重点)。

简单介绍一下,对于 JavaScript 的基本类型来说,直接使用 = 运算符赋值是没有问题的,但是对于对象来说,就会发生这样的问题:

let obj0 = {name: 'Double'};
let obj1 = obj0;
obj1.name = 'Click';
console.log(obj0.name); // 输出 Click

这就是因为对象是引用类型,也就是说,变量 obj0 和 obj1 中存储的都是对象的引用,它俩指向的是同一个对象,所以修改了 obj1.name 也会导致 obj0.name 改变。

简单实现

如何实现一个对象的深拷贝,逻辑上并没有太多的难点,既然对象是引用类型,但对象里的内容追根到底也是由基本类型构成的,如果对象某个 key 的 value 是对象的话,那我只要递归复制就可以了。

let deepCopy = obj => {
    let ret = {};

    Object.keys(obj).map(key => {
        const value = obj[key];

        if (typeof value === 'object') {
            ret[key] = deepCopy(value);
        } else {
            ret[key] = value;
        }
    });
    return ret;
};

看起来不错,but...

标签: none

已有 3 条评论

  1. vbyzc vbyzc

    大哥,在推酷上看到你的文章,忍不住有个问题咨询, es6应该无法在浏览器上得到支持吧? 如果测试学习的话应该是否要node+babel环境才能运行? 近来看了太多的教程或心得文章,很多都有es6的语法,包括你本人,是否都是这些人习惯用es6来做项目,写出来的文章也是带有es6语法?

    1. es6 的大多数语法都已经在浏览器上实现了,很多情况下都可以在浏览器上直接跑了。
      不过目前前端的大多数都是 node + webpack + babel 那一套了,因为不仅仅需要支持 es6 的语法,比如如果你写 React 的话,还要支持 jsx 语法,写 Vue 的话,也要支持那一套模板语法。

      1. vbyzc vbyzc

        感谢回复!

添加新评论