低开开发笔记(五):修bug-深拷贝与浅拷贝

好家伙

今天遇到一个bug

0.问题描述

描述如下:

代码如下:

复制代码
copynodefunc() {
            this.copynode = this.model.selected
        },
        affixnode() {
            const id = this.model.selected.wid - 1;
            const goodnode = this.copynode
            this.dsl.children.splice(id, 0, goodnode);
            this.numberreset();
        },

1.问题分析

我么的model.selected长这个样子

复制代码
{
    "wid": 1,
    "component": "ph-radio",
    "props": {
        "No": 1,
        "title": "我是输入框",
        "options_1": "选项一一",
        "options_2": "选项二二"
    },
    "style": {
        "top": "300px",
        "left": "300px",
        "zIndex": "1",
        "border": "1px dashed red"
    },
    "attrs": {},
    "events": {}
}

根据我多年开发bug的经验分析,这大概是引用出了问题

在上面的数据中,model.selected中的props是一个对象,估计在拷贝的时候没有进行深拷贝,拷贝的只是对象的引用

2.修改bug

于是,我们试着

将代码改为

复制代码
copynodefunc() {
            this.copynode = this.model.selected
        },
        affixnode() {
            const id = this.model.selected.wid - 1;
            const goodnode = {...this.copynode}
            this.dsl.children.splice(id, 0, goodnode);
            this.numberreset();
        },

没什么用

又想到了我们的Object.assign(),但是,没有用,Object.assign()也是浅拷贝

所以,我们自己写一个深拷贝吧

3.深拷贝代码

复制代码
export function deepCopy(obj) {
    var objClone ={};
    if (obj && typeof obj === "object") {
        for (var key in obj) {
            if (obj.hasOwnProperty(key)) {
                if (obj[key] && typeof obj[key] === "object") {
                    objClone[key] = deepCopy(obj[key]);
                } else {
                    objClone[key] = obj[key];
                }
            }
        }
    }
    return objClone;
}

代码解释如下:

这段代码定义了一个名为 deepCopy 的函数,用于实现深拷贝(deep copy)操作。深拷贝是指在拷贝对象时,不仅复制对象本身,还会递归复制对象内部的所有子对象,确保原对象和拷贝后的对象完全独立,互不影响。

下面是对代码的详细解释:

  1. export function deepCopy(obj) { ... }:定义了一个导出的函数 deepCopy,该函数接受一个参数 obj,表示需要进行深拷贝的对象。

  2. var objClone = {};:初始化一个空对象 objClone,用于存储深拷贝后的对象。

  3. if (obj && typeof obj === "object") { ... }:首先判断传入的参数 obj 是否存在且为对象类型,确保只对对象进行深拷贝操作。

  4. for (var key in obj) { ... }:使用 for...in 循环遍历对象 obj 的所有可枚举属性,其中 key 为当前属性的键名。

  5. if (obj.hasOwnProperty(key)) { ... }:通过 hasOwnProperty 方法判断当前属性是否为对象自身的属性,而非继承自原型链上的属性。

  6. if (obj[key] && typeof obj[key] === "object") { ... }:若当前属性的值是对象类型,则递归调用 deepCopy 函数进行深拷贝,将结果存储在 objClone[key] 中。

  7. else { objClone[key] = obj[key]; }:若当前属性的值不是对象类型,则直接将其赋给 objClone[key],实现浅拷贝。

  8. return objClone;:返回深拷贝后的对象 objClone

总结:该函数通过递归的方式,对传入的对象进行深拷贝操作,确保拷贝后的对象与原对象完全独立。需要注意的是,该函数仅适用于处理普通对象,对于包含函数、原型链等特殊情况需要进行额外处理。

搞定。