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

使用数组元素定位另一数组索引时,原数组数据为何变更?

问题分析与解决:CASHVALUES数组意外被修改的原因

核心问题出在这两行代码:

const currentDenomination = CASHVALUES[i][1];

change[change.indexOf(CASHVALUES[i])][1] += currentDenomination;

每次执行这段代码时,CASHVALUES[i][1]的值都会意外翻倍。原本预期只有change数组的数据会被修改,尝试将CASHVALUES的克隆值赋值给currentDenomination也无法解决问题。

完整问题代码片段:

function checkCashRegister(price, cash, cid) {
  let cid = [["PENNY", 1.01], ["NICKEL", 2.05], ["DIME", 3.1], ["QUARTER", 4.25], ["ONE", 90], ["FIVE", 55], ["TEN", 20], ["TWENTY", 60], ["ONE HUNDRED", 100]];

  const CASHVALUES = [["ONE HUNDRED", 100], ["TWENTY", 20], ["TEN", 10], ["FIVE", 5], ["ONE", 1], ["QUARTER", 0.25], ["DIME", 0.1], ["NICKEL", 0.05], ["PENNY", 0.01]];

  let changeDue = (cash - price);
  const TotalChangeDue = changeDue
  let change = [];
  let status = "OPEN";

  cid.reverse();

  for(let i=0;i<CASHVALUES.length;i++) {
    const currentDenomination = CASHVALUES[i][1];
    
    if(changeDue >= currentDenomination) {
      if(cid[i][1] > 0) {
        cid[i][1] -= currentDenomination;
        cid[i][1] = cid[i][1].toFixed(2);
        changeDue -= currentDenomination;
        changeDue = changeDue.toFixed(2);
        if(!change.includes(CASHVALUES[i])) {
          change.push(CASHVALUES[i]);
        }
        else {
          change[change.indexOf(CASHVALUES[i])][1] += currentDenomination;
        } 
          i--;     
        
      }
          
    }
  }
}

问题根源

这是典型的引用类型赋值导致的问题:

  • CASHVALUES中的元素是数组(属于引用类型),当你执行change.push(CASHVALUES[i])时,并没有把数组的副本加入change,而是把该数组的内存引用直接添加进去了。
  • 这意味着change里的元素和CASHVALUES里的对应元素指向的是同一个内存地址。当你执行change[...][1] += currentDenomination时,本质上是在修改CASHVALUES[i][1]本身,因为两者是同一个引用。
  • 你尝试克隆currentDenomination没用,因为currentDenomination是数值(基本类型),克隆它无法解决数组引用共享的问题。

解决方案

要解决这个问题,需要在将CASHVALUES的元素加入change时,创建数组的副本,而不是直接添加引用。同时,改用币种名称判断元素是否存在(引用比较不可靠),修改后的核心逻辑如下:

// 替换原有的if-else判断逻辑
const denominationName = CASHVALUES[i][0];
const existingItemIndex = change.findIndex(item => item[0] === denominationName);

if (existingItemIndex === -1) {
  // 创建新数组副本加入change,避免引用共享
  change.push([denominationName, currentDenomination]);
} else {
  // 修改change中的对应项,不会影响CASHVALUES
  change[existingItemIndex][1] += currentDenomination;
}

另外还有两个额外的坑需要修正:

  • cid[i][1].toFixed(2)和changeDue.toFixed(2)会把数值转为字符串,后续的加减运算会出现字符串拼接的错误,建议保留数值类型,仅在最终输出结果时进行格式化。
  • 原代码中change.includes(CASHVALUES[i])是引用比较,即使两个数组内容完全一致,只要引用不同就会返回false,改用币种名称判断更可靠。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 10:11:07