You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript服务运行时为何原常量对象被意外修改,如何规避?

问题解答

根本原因

  • Object.assign 是浅拷贝,仅会复制对象的第一层属性,不会递归复制深层的引用类型属性。你执行Object.assign({}, dataSchema())的时候,新创建的dataScheme对象的project属性,仍然和原objData的project属性指向同一个内存地址,修改dataScheme.project下的属性本质就是修改原objData的内容。
  • 你的dataSchema函数每次都返回同一个全局objData的引用,多次调用拿到的都是同一个根对象的引用,第一次修改后原对象就被污染了,后续调用拿到的都是被修改过的值。

解决方案

方案1(优先推荐):每次调用dataSchema时返回全新的schema对象

不要复用全局的objData,直接在函数内生成新对象,从根源避免引用共享,无额外性能损耗:

const dataSchema = () => {
    return {
        project: {
            name: '',
            age: 0,
            subProject: {
                name: '',
                age: 0
            }
        }
    }
}

修改后无需改动其他逻辑,即可正常运行。

方案2:对schema做深拷贝

如果一定要复用全局的schema对象,把原有的浅拷贝逻辑替换为深拷贝即可:

const mappingData1 = (data) => {
    try {
        // 用JSON序列化反序列化实现深拷贝,适用于schema无函数、Symbol、循环引用的场景
        const dataScheme = JSON.parse(JSON.stringify(dataSchema()))
        dataScheme.project.name = data.name;
        dataScheme.project.age = data.age;

        return dataScheme;
    }catch(err){
        return err;
    }
}
// mappingData2做相同的拷贝逻辑修改即可

如果项目已经引入了lodash,也可以直接用_.cloneDeep(dataSchema())实现深拷贝。

方案3:逐层展开创建新对象

适合需要精细控制拷贝层级的场景,性能比通用深拷贝更高:

const dataScheme = {
    ...dataSchema(),
    project: {
        ...dataSchema().project,
        subProject: {
            ...dataSchema().project.subProject
        }
    }
}

内容的提问来源于stack exchange,提问作者masdap

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 18:45:02