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

TypeScript深度克隆动态生成对象时返回空对象的异常问题排查

TypeScript深度克隆动态生成对象时返回空对象的异常问题排查

嘿,这个问题看起来挺诡异的,但其实根源就在你创建facetValues对象的方式上!我来给你拆解清楚:

问题核心原因

你用Object.defineProperty给facetValues添加属性的时候,没有设置enumerable: true,而这个属性的默认值是false——也就是说,你添加的status、plan这些属性都是不可枚举的!

而你用到的两种克隆方式:lodash的_cloneDeep和JSON.parse(JSON.stringify()),都是依赖对象的可枚举属性来完成复制的。它们会跳过不可枚举的属性,自然就返回空对象了。

至于为什么console.log(fullValues)能显示出这些属性?那是因为浏览器控制台会展示对象的所有属性(包括不可枚举的),这很容易给人造成“属性正常”的错觉,但克隆工具可不认这个。

对比验证

你后面用字面量直接创建的对象:

let fullValues: { [key : string ] : Array<string> }  = { status: [], plan: [] };

这里的属性默认是可枚举的,所以克隆工具能正常识别,自然就返回正确的结果了。

解决方案

有两种简单的修复方式:

1. 给Object.defineProperty添加enumerable: true配置

修改你创建facetValues的代码:

const facetValues: { [key: string]: Array<string> } = {};

if (facetedData) {
    Object.entries(facetedData).forEach(([key, value]) => {
        Object.defineProperty(facetValues, key, { 
            value: [] as string[],
            enumerable: true // 关键:显式设置属性可枚举
        });
    });
}

2. 直接赋值创建属性(更简洁)

其实完全没必要用Object.defineProperty,直接给对象赋值就能创建可枚举属性:

const facetValues: { [key: string]: Array<string> } = {};

if (facetedData) {
    Object.entries(facetedData).forEach(([key]) => {
        facetValues[key] = []; // 直接赋值,属性默认可枚举
    });
}

修改之后,你再用_cloneDeep或者JSON方法克隆,就能得到包含所有属性的对象啦!

备注:内容来源于stack exchange,提问作者mani-hash

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.14 12:38:04