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

JS将对象push到数组后与原对象内容不一致,是什么原因导致的?

问题根因

1. 对象引用类型特性导致数据被覆盖

JavaScript 中的普通对象属于引用数据类型,你遍历SP500拿到的y是原数组中对象的内存引用,执行data.push(y)时只是把这个引用存进了data数组,并没有独立复制一份对象。
你在循环里直接给y.cumulativeReturn赋值,本质是修改原数组中对象的属性,之前已经存到data里的引用指向的是同一个原对象,所以属性会同步被后续循环的计算结果覆盖。
另外你调用的SP500.reverse()是原地修改方法,会直接改变原始SP500数组的元素顺序,还会污染全局的原始数据。

2. 浏览器控制台的懒加载特性

浏览器console.log打印对象/数组时,输出的是对象的引用快照,你点击展开打印结果时才会读取对象当前的最新属性值,不是执行log语句那一刻的属性值,这也会让你看到的打印结果和预期执行时刻的数值不一致。


修复代码

只需要在操作时避免修改原对象,推入data时存入独立的新对象即可,同时反转数组前先复制原数组避免污染原始数据:

export const fetchSP500 = (year) => {
    let data = [];
    let cumulativeReturn = 1;
    // 复制原数组后再反转,不修改原始SP500
    [...SP500].reverse().forEach(y => {
        cumulativeReturn *= ((y.totalReturn * .01) + 1);
        const curCumulative = ((cumulativeReturn - 1) * 100);
        if (y.year >= year[0] && y.year <= year[1]) {
            // 创建新对象存入,不修改原y对象
            data.push({
                ...y,
                cumulativeReturn: curCumulative
            });
        }
    })
    return data;
}

如果需要打印准确的时刻快照,可以把对象转成JSON再转回对象打印,规避控制台懒加载的影响:

console.log('当前data快照:', JSON.parse(JSON.stringify(data)))

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 01:27:00