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

React函数无法正确构造数组的问题排查

函数生成默认数据时的异常行为问题

问题描述

我写了一个生成默认数据的函数,代码如下:

const generateDefaultDataForModel = (data: any) => {
        const numBlocks = data && Object.keys(data).length > 0 ? data[Object.keys(data)[0]].length : 3;
        console.log("numBlocks", numBlocks);

        const defaultWeight = 1 / Object.keys(originalWeights).length;
        console.log("defaultWeight", defaultWeight);

        const defaultData = Array.from({ length: numBlocks }, () => [defaultWeight, true]);
        console.log("defaultData", defaultData);

        const test = Array.from({ length: numBlocks }, () => [defaultWeight, true]);    
        console.log("test", test);

        return test;
};

触发onClick调用该函数时,控制台显示numBlocks=3、defaultWeight=0.9,但defaultData生成的是[[0, true], [0, true], [0, true]],后续完全相同代码生成的test却是[[0.9, true], [0.9, true], [0.9, true]]。试过修改变量名、硬编码数值都没解决,甚至注释掉defaultData这一行后,test也会输出错误结果。

补充调用信息

调用函数的代码如下:

const newCurrentWeights = JSON.parse(JSON.stringify(currentWeights));

generateDefaultDataForModel(originalWeights);
newCurrentWeights[model] = generateDefaultDataForModel(originalWeights);

currentWeights的结构为{key: {key: [value, bool]}}。单独调用generateDefaultDataForModel(originalWeights)输出正确,但赋值给newCurrentWeights[model]时就会出现错误。


问题原因分析

  1. originalWeights的键数量在两次调用间发生变化
    函数中defaultWeight的计算依赖Object.keys(originalWeights).length,第二次调用函数时,这个长度可能已经被意外修改(比如第一次调用的副作用、JSON.parse(JSON.stringify)的间接影响,或是其他关联代码的修改),导致1/长度的结果被稀释为接近0的数值,只是控制台打印的顺序可能让你误以为defaultWeight还是0.9。

  2. 闭包引用的变量被后续操作修改
    Array.from的回调是闭包,它引用的defaultWeight如果在回调执行前被意外修改(比如异步逻辑干扰、其他代码的副作用),会导致生成的数组元素值异常。不过结合控制台打印的内容,更可能是第二次调用时defaultWeight的计算值本身就变了。

  3. originalWeights与currentWeights存在引用关联
    如果originalWeights是currentWeights的引用而非深拷贝,那么JSON.parse(JSON.stringify(currentWeights))后的操作可能间接修改了originalWeights的结构,导致第二次调用函数时计算出的defaultWeight异常。


验证与修复建议

  • 先在两次调用前打印originalWeights的键数量,确认是否变化:
    console.log("首次调用前的originalWeights长度:", Object.keys(originalWeights).length);
    generateDefaultDataForModel(originalWeights);
    console.log("二次调用前的originalWeights长度:", Object.keys(originalWeights).length);
    newCurrentWeights[model] = generateDefaultDataForModel(originalWeights);
    
  • 固化defaultWeight的值,避免闭包引用的潜在问题:
    const defaultWeight = 1 / Object.keys(originalWeights).length;
    // 用新变量固化数值,避免后续意外修改影响闭包
    const fixedWeight = defaultWeight;
    const defaultData = Array.from({ length: numBlocks }, () => [fixedWeight, true]);
    const test = Array.from({ length: numBlocks }, () => [fixedWeight, true]);  
    
  • 检查所有涉及originalWeights的代码,确认是否存在未预期的修改操作(比如赋值、添加/删除键)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 04:00:12