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

bug · 浏览次数 : 0

小编点评

**问题描述:** 代码中`copynodefunc()`函数中存在以下问题: 1. `this.copynode = this.model.selected` 中的属性`props`是一个对象,在浅拷贝时没有进行深拷贝,导致引用的问题。 2. `Object.assign()`尝试深拷贝对象,但因为对象本身是引用类型,导致浅拷贝。 **修改方案:** 1. 使用深拷贝函数`deepCopy()`进行深拷贝。 2. 在`deepCopy()`中,递归调用自身进行深拷贝,处理对象属性和子对象的属性。 3. 将`this.copynode`赋给`objClone`,实现对对象的深拷贝。 **代码修改:** ```js 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()`函数仅适用于处理普通对象,对于包含函数、原型链等特殊情况需要进行额外处理。 * 在深拷贝过程中,如果遇到无法访问属性的错误,可以尝试使用`Object.getOwnPropertyDescriptors()`获取属性描述符,并通过遍历属性描述符来实现深拷贝。

正文

好家伙

 

今天遇到一个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

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

 

搞定。

 

与低开开发笔记(五):修bug-深拷贝与浅拷贝相似的内容:

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

好家伙 今天遇到一个bug 0.问题描述 描述如下: 代码如下: copynodefunc() { this.copynode = this.model.selected }, affixnode() { const id = this.model.selected.wid - 1; const g

低开开发笔记(八): 低代码编辑器实现撤销回退(命令模式,防抖处理)

好家伙, 0.代码已开源 https://github.com/Fattiger4399/ph_questionnaire-.git 1.事件触发 我们先从事件的触发开始讲起 大致上我们有两个思路可以选择 1.监控用户行为 2.监控数据变化 两种选择都会有较难处理的部分,这里我们先选第二个选项 关于

低开开发笔记(六): 工作台与模板样式开发

好家伙,仅仅只是实现了样式,完整功能暂未完成 完整代码已开源 https://github.com/Fattiger4399/ph-questionnaire.git 1.灵感来源 (抄袭对象) 刚开始想着随便写个低开项目练练手的,然后就写成这样了 1.1.简道云 1.2.问卷星 2.上代码

低开开发笔记(二):低代码编辑器基本原理

好家伙, 完整代码已开源 https://github.com/Fattiger4399/ph-questionnaire.git 本片我们来讲述 如何将dsl的数据渲染为视图 1.数据格式 dsl: { component: 'div', wid: 0, props: { }, style: {

Gitee千Star优质项目解析: ng-form-element低开引擎解析

好家伙, 在写项目的时候,我发现自己的平台的组件写的实在是太难看了,于是想去gitee上偷点东西,于是我们本期的受害者出现了 gitee项目地址 https://gitee.com/jjxliu306/ng-form-elementplus-sample.git 组件库以及引擎完全开源,非常牛逼的项

Karmada v1.5发布:多调度组助力成本优化

摘要:在最新发布的1.5版本中,Karmada 提供了多调度组的能力,利用该能力,用户可以实现将业务优先调度到成本更低的集群,或者在主集群故障时,优先迁移业务到指定的备份集群。 本文分享自华为云社区《Karmada v1.5发布!多调度组助力成本优化》,作者:华为云云原生团队。 Karmada 是开

Ui2Code+ChatGPT助力低代码搭建

低代码开发平台(LCDP),是低代码或无代码通过快速搭建配置的方式完成一个应用程序的开发与上线,可视化低代码就是可视化的DSL,它的优点更多的是来源可视化,相对的,它的局限性也还是来源于可视化,复杂的业务逻辑用低代码可能会更加复杂。低代码应该是特定领域问题的简化和抽象,如果只是单纯将原有的编码工作转换为 GUI 的模式,并没有多大意义。

LuBase 低代码开发框架介绍 - 可私有化部署

框架定位 面向开发人员,针对管理软件领域,对页面交互和通用功能进行高阶封装,逐步打造成平台型、生态型开发工具。 涓涓细流 ,汇聚成海,基于 PBC(组件式开发)开发理念,让功能模块的复用更简单。 让管理软件开发回归到对需求的深入思考和求解。 框架简介 LuBase 是以数据模型驱动,可视化表单和页面

ChatGPT赋能低代码开发:打造智能应用的双重引擎

摘要:本文摘自葡萄城低代码产品活字格的资深用户(格友超哥)所撰写的文章:《惊叹表现!活字格+ChatGPT:低代码开发智能应用的巨大潜力》。 ChatGPT的functions函数使用方 自从OPENAI发布了最新的GPT引擎gpt-3.5-turbo-0613之后,我就对它的functions参数

为什么现代的低代码开发平台都不支持导出源代码?

> 摘要:本文由葡萄城技术团队于博客园原创并首发。葡萄城为开发者提供专业的开发工具、解决方案和服务,赋能开发者。 初次接触低代码的程序员大多会纠结一个问题,为什么功能越强大的低代码开发平台越不会提供导出源代码的功能? 要想回答这个问题,我们得回顾一下低代码开发的发展史。事实上,支持导出[源代码](h