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

Angular/TypeScript处理API图表数据时数组输出异常问题求助

问题分析与解决方案

你碰到的这个控制台显示异常+数据被覆盖的问题,本质是数组引用复用导致的,浏览器控制台的“诡异”表现只是这个问题的外在体现而已。

先解释控制台的奇怪现象

浏览器控制台打印引用类型(比如数组、对象)时,初始显示的是打印那一刻的“快照”,但当你展开它时,会去读取这个对象的当前状态。因为你所有的dataset.data都指向同一个tempRates数组,最后这个数组被修改成了全1,所以展开后看到的都是1,而初始快照是当时的正确值——这不是控制台bug,是它的工作机制。

代码里的核心问题

你在循环中一直复用同一个tempRates数组,每次往this.data.datasets里push的时候,传递的是这个数组的引用,而不是它的副本。这就相当于所有dataset的data都“共享”同一个数组,后续对tempRates的清空(tempRates.length = 0)或者修改,都会同步影响之前所有已经push进去的数组引用。最后一个数组没被清空,所以它的值保留了全1,前面的数组因为引用指向同一个对象,也跟着变成了全1。

修复方案

解决的关键是给每个dataset的data提供独立的数组实例,不要复用同一个数组。有两种简单的方式:

方案1:每次循环创建新的tempRates

把tempRates的初始化放到循环内部,这样每次迭代都是全新的数组:

let i = 0; // 确保i提前初始化
// 先处理日期标签
Object.keys(data.rates).forEach((key) => { 
  this.data.labels.push(key);
}); 
// 处理汇率数据
Object.values(data.rates).forEach((value) => { 
  // 每次循环新建数组,不再复用
  const tempRates: number[] = [];
  const tempCurrency = Object.keys(value)[i]; 
  Object.values(data.rates).forEach((rate) => { 
    if (tempCurrency === Object.keys(rate)[i]) { 
      tempRates.push(rate[tempCurrency]); 
    } 
  }); 
  // 打印的时候也可以用扩展运算符创建副本,避免控制台显示误导
  console.log("log before push", [...tempRates]); 
  this.data.datasets.push({ 
    label: tempCurrency, 
    data: tempRates, // 现在每个data都是独立的数组
  }); 
  i++; 
});

方案2:在push时创建数组副本

如果你想保留原来的变量结构,就在往datasets里push的时候,用扩展运算符或者Array.from()创建数组的副本:

let i = 0;
const tempRates: number[] = [];
Object.keys(data.rates).forEach((key) => { 
  this.data.labels.push(key);
}); 
Object.values(data.rates).forEach((value) => { 
  tempRates.length = 0; // 清空数组
  const tempCurrency = Object.keys(value)[i]; 
  Object.values(data.rates).forEach((rate) => { 
    if (tempCurrency === Object.keys(rate)[i]) { 
      tempRates.push(rate[tempCurrency]); 
    } 
  }); 
  console.log("log before push", [...tempRates]); 
  this.data.datasets.push({ 
    label: tempCurrency, 
    data: [...tempRates], // 传递副本,而非引用
  }); 
  i++; 
});

额外小提示

以后调试引用类型的时候,要是想看到打印那一刻的真实值,最好打印它的副本(比如[...tempRates]或者JSON.parse(JSON.stringify(tempRates))),这样就不会被后续的修改影响控制台的显示结果了。

内容的提问来源于stack exchange,提问作者Imra Kočiš

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.27 20:42:31