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 时,遵循固定逻辑:
检查对象
obj中是否存在名为key的属性;如果不存在:直接为对象新增该属性,并赋值
value;如果已存在:覆盖该属性原有的值为
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 }(仅更新值)总结
acc[cur] = ...这种赋值方式,如果属性不存在则自动新增,存在则更新值,这是 JS 对象的原生行为;(acc[cur] || 0)的作用是处理“属性不存在时的值为undefined”的问题,确保累加逻辑不会变成undefined + 1(结果为NaN);这行代码正是利用了“赋值自动新增属性”的特性,才能从空对象开始,逐步给每个水果新增属性并统计数量。
(注:文档部分内容可能由 AI 生成)