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

为何JavaScript中Array.reduce()的两个计数器实现效果不同?

JavaScript Array.reduce()中两种累加写法的差异原因

问题描述

在以下两个Array.reduce()示例中,为何第二个reducer里的count能正常递增,而第一个却始终保持初始值?同时需要解决为初始对象部分属性自定义名称的场景需求。

示例1:count无法递增的写法

const data = [1,2,3,4];

data.reduce((accumulator) => {
    let { count } = accumulator;
    count++;
    console.log(accumulator);
    return accumulator;
}, { count: 0 });

/*
输出结果:
{ count: 0 }
{ count: 0 }
{ count: 0 }
{ count: 0 } 
*/

示例2:count正常递增的写法

data.reduce((accumulator) => {
    accumulator.count++;
    console.log(accumulator);
    return accumulator;
}, { count: 0 });

/* 
输出结果:
{ count: 1 }
{ count: 2 }
{ count: 3 }
{ count: 4 } 
*/

核心原因

基本类型与引用类型的传递差异

  • 示例1中,let { count } = accumulator是解构赋值,这里的count是数字类型(基本类型)。基本类型在赋值时是值传递——相当于把accumulator.count的数值复制了一份给新变量count。后续执行count++只是修改了这个副本,完全没改动原对象accumulator里的count属性,所以每次打印原对象都是初始值0。
  • 示例2中,accumulator.count++是直接操作原对象的属性。对象属于引用类型,操作对象属性时直接修改的是原对象本身,所以每次递增都会改变原对象的count值,打印结果自然是递增的。

自定义属性名称的解决方法

如果需要解构时自定义属性名称(比如把count重命名为customCount),同时要修改属性值,可以用以下两种方式:

方式1:修改原对象属性

data.reduce((accumulator) => {
    // 解构时自定义属性名
    let { count: customCount } = accumulator;
    customCount++;
    // 将修改后的值赋值回原对象的属性
    accumulator.count = customCount;
    console.log(accumulator);
    return accumulator;
}, { count: 0 });

方式2:返回新对象(无副作用)

如果不想修改原对象,而是返回一个新对象,适合纯函数场景:

data.reduce((accumulator) => {
    let { count: customCount } = accumulator;
    customCount++;
    // 展开原对象,覆盖count属性
    const newAccumulator = { ...accumulator, count: customCount };
    console.log(newAccumulator);
    return newAccumulator;
}, { count: 0 });

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 22:30:29