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

JS使用reduce统计数组元素重复次数时方括号与点符号输出差异问题

问题原因分析

核心区别:点表示法 vs 方括号表示法

  • 点表示法后面的字段会被当成固定的字符串字面量,不会被解析为变量
  • 方括号内的内容会先计算取值,再将计算结果作为属性名访问

代码运行逻辑拆解

你提供的测试代码整理如下:

let data = ['car', 'car', 'truck', 'truck', 'bike', 'walk', 'car', 'van', 'bike', 
'walk', 'car', 'van', 'car', 'truck', 'Pogo '];

// 方括号写法,结果正常
let instance_1 = data.reduce((acc, elm) => {
  if(!acc[elm]){
    acc[elm] = 0;
  }
  acc[elm]++;
  return acc;
}, {})
console.log(instance_1)

// 点表示法,结果异常
let instance_2 = data.reduce((acc, elm) => {
  if(!acc.elm) {
    acc.elm = 0;
  }
  acc.elm++;
  return acc;
}, {})
console.log(instance_2);

instance_1 输出正常的原因

你用acc[elm]访问属性时,方括号里的elm会被解析为当前遍历到的数组元素值,比如第一次循环elm是'car',就等价于访问acc['car'],后续循环会根据当前元素值动态切换访问的属性名,累加后就能得到每个元素的出现次数。
最终instance_1的输出为:

{ car: 5, truck: 3, bike: 2, walk: 2, van: 2, 'Pogo ': 1 }

instance_2 输出异常的原因

你用acc.elm访问属性时,这里的elm不会被识别为你定义的循环变量,而是被当成一个名字叫elm的固定属性,和你当前遍历的元素值完全无关。整个reduce循环的15次遍历,每次都是给acc.elm这个属性累加1,所以最终instance_2的输出只会是:

{ elm: 15 }

使用建议

  • 如果你要访问的属性名是固定、符合标识符命名规范的,用点表示法更简洁,比如obj.name、obj.age
  • 如果你要访问的属性名是动态变量、包含特殊字符/空格/数字开头,必须用方括号表示法,你的统计场景属于动态属性名的情况,只能用方括号实现。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 17:27:04