实现一个JS深拷贝函数

摘要:JS深拷贝概念并不新鲜,但是真正要真正理解原理还是有点难度的。这也是JS语言精粹之一吧。因为JS对于对象的赋值使用的是浅拷贝,其中一个实例变量的赋值会影响到所有指向该对象的变量

JS深拷贝概念并不新鲜,但是真正要真正理解原理还是有点难度的。这也是JS语言精粹之一吧。


例子

let a = {
    name: 'demo',
    age: 18
};

let b = a;
b.name = 'demo1';

console.log(a); // 输出 {name: "demo1", age: 18}
console.log(b); // 输出 {name: "demo1", age: 18}

因为JS对于对象的赋值使用的是浅拷贝,其中一个实例变量的赋值会影响到所有指向该对象的变量


解决方案

粗暴好使的 JSON.parse(JSON.stringify),缺点: 丢失成员函数

Object.assign,缺点:只有第一级深拷贝,子级对象依旧是浅拷贝,例子如下:

let a = {name:{demo:'1'}};
let b = Object.assign({}, a);
console.log(a); // 输出 {name:{demo:'1'}}
console.log(b); // 输出 {name:{demo:'1'}}
b.name.demo = '2';
console.log(a); // 输出 {name:{demo:'2'}}
console.log(b); // 输出 {name:{demo:'2'}}


手动实现原理

遍历待拷贝对象

判断当前值类型,如果是object类型且不是null(null也是object),则递归调用拷贝函数

如果当前值类型时null或者非object类型,直接return,退出本次递归


编码实现

function deepCopy(obj) {
    let result = obj;
    if(typeof obj === 'object' && obj !== null) {
        result = Object.prototype.toString.call(obj) === '[object Array]' ? []: {};
        for(let prop in obj) {
            result[prop] = deepCopy(obj[prop]);
        }
    }
    return result;
}

验证一下:

let a = {name:{demo:'1'}};
let b = deepCopy(a);
console.log(a); // 输出 {name:{demo:'1'}}
console.log(b); // 输出 {name:{demo:'1'}}
b.name.demo = '2';
console.log(a); // 输出 {name:{demo:'1'}}
console.log(b); // 输出 {name:{demo:'2'}}

来自:https://www.ddhigh.com/2019/07/16/make-a-deep-copy-function.html

本文内容仅供个人学习、研究或参考使用,不构成任何形式的决策建议、专业指导或法律依据。未经授权,禁止任何单位或个人以商业售卖、虚假宣传、侵权传播等非学习研究目的使用本文内容。如需分享或转载,请保留原文来源信息,不得篡改、删减内容或侵犯相关权益。感谢您的理解与支持!

链接: https://shenqiku.cn/article/FLY_4209