Skip to content

JavaScript 对象属性赋值分析:从空对象到属性统计

acc[cur] = (acc[cur] || 0) + 1; 这行代码里给对象的某个属性赋值,确实隐含着先给对象添加该属性(如果这个属性原本不存在的话)。

分步拆解这行代码的执行逻辑

我们结合之前统计水果数量的例子(acc 是初始为空的对象 {}cur 是遍历到的水果名,比如 apple),一步步看:

1. 第一次遇到某个属性(比如 apple

此时 acc{}acc['apple'] 不存在,返回 undefined

JavaScript

// (acc[cur] || 0) 等价于 (undefined || 0),结果是 0
// 然后执行 0 + 1 = 1
acc['apple'] = 1;
  • 因为 acc 原本没有 apple 属性,执行 acc['apple'] = 1 时,JS 会先给 ** acc ** 对象新增 ** apple ** 这个属性,再把值 1 赋给它。

  • 执行后 acc 变成 { apple: 1 }

2. 再次遇到同一个属性(比如又遍历到 apple

此时 acc 已有 apple 属性,值为 1

JavaScript

// (acc[cur] || 0) 等价于 (1 || 0),结果是 1
// 然后执行 1 + 1 = 2
acc['apple'] = 2;
  • 这时候属性已存在,只是更新属性值,而非新增。

补充:JS 中对象属性赋值的规则

在 JavaScript 中,对对象的属性执行 obj[key] = value 时,遵循固定逻辑:

  1. 检查对象 obj 中是否存在名为 key 的属性;

  2. 如果不存在:直接为对象新增该属性,并赋值 value

  3. 如果已存在:覆盖该属性原有的值为 value

这是 JS 对象的原生特性,和 reduce 无关,只要是给对象的属性赋值,都会遵循这个规则。

举个更直观的例子验证

JavaScript

// 初始化空对象
const obj = {};
console.log(obj.age); // undefined(无age属性)

// 给不存在的属性赋值 → 新增属性
obj.age = 18;
console.log(obj); // { age: 18 }(已新增age属性)

// 给已存在的属性赋值 → 更新值
obj.age = 20;
console.log(obj); // { age: 20 }(仅更新值)

总结

  1. acc[cur] = ... 这种赋值方式,如果属性不存在则自动新增,存在则更新值,这是 JS 对象的原生行为;

  2. (acc[cur] || 0) 的作用是处理“属性不存在时的值为 undefined”的问题,确保累加逻辑不会变成 undefined + 1(结果为 NaN);

  3. 这行代码正是利用了“赋值自动新增属性”的特性,才能从空对象开始,逐步给每个水果新增属性并统计数量。

(注:文档部分内容可能由 AI 生成)

最近更新