• 主页
  • 个人简介
    • 圣墨 photo

      圣墨

      一个爱折腾,有诗有远方的人

    • Learn More
    • Github
    • Cnblogs
    • Weibo
  • 文章
    • 所有文章
    • 所有标签
  • Html&Css
  • Javascript
  • 设计模式
  • 前端性能优化
  • 原生实现专题
  • 数据结构与算法
  • Book
  • 面试题
  • 前端工具
  • 随记

手动实现深拷贝

10 Oct 2019

Reading time ~1 minute

手动实现深拷贝

一、浅拷贝和深拷贝的定义

  • 浅拷贝: 创建一个新对象,这个对象有着原始对象属性值的一份精确拷贝。如果属性是基本类型,拷贝的就是基本类型的值,如果属性是引用类型,拷贝的就是内存地址 ,所以如果其中一个对象改变了这个地址,就会影响到另一个对象。

  • 深拷贝: 将一个对象从内存中完整的拷贝一份出来,从堆内存中开辟一个新的区域存放新对象,且修改新对象不会影响原对象

二、实现深拷贝

乞丐版

JSON.parse(JSON.stringify());
  • 缺陷: 这种写法非常简单,而且可以应对大部分的应用场景,但是它还是有很大缺陷的,比如拷贝其他引用类型、拷贝函数、循环引用等情况。

基础版本

function clone(target) {
    if (typeof target === 'object') {
        let cloneTarget = {};
        for (const key in target) {
            cloneTarget[key] = clone(target[key]);
        }
        return cloneTarget;
    } else {
        return target;
    }
};

// 测试
const target = {
    field1: 1,
    field2: undefined,
    field3: 'ConardLi',
    field4: {
        child: 'child',
        child2: {
            child2: 'child2'
        }
    }
};

缺陷: 没有考虑数组

考虑数组

function clone(target) {
    if(typeof target === 'object') {
        let cloneTarget =  Array.isArray(target)? [] : {}
        for(const k in target) {
            cloneTarget[k] = clone(target[k])
        } 
        return cloneTarget;
    } else {
        return target;
    }
}

// 测试
const target = {
field1: 1,
field2: undefined,
field3: 'ConardLi',
field4: {
    child: 'child',
    child2: {
        child2: [1,2,3,4]
    }
}
};

const res = clone(target);
console.log(res);

深拷贝到此已经很不错了,但还要考虑其他情况未完待续……

学习参考:

非常非常感谢:如何写出一个惊艳面试官的深拷贝



javascript  微博  QQ  朋友圈