JavaScript中用键值对统计数组元素出现次数的原理疑问
数组元素出现次数统计的两种JS实现逻辑解析
这是Udemy的JavaScript课程里的一个挑战任务:从给定数组创建键值对对象,用数组元素作为key,元素的出现次数作为value。对应的两种实现代码如下:
const sequential = ["first", "second", "third", "forth", "first", "first"]; const sequentialObject1 = {}; const sequentialObject2 = {}; for (const seq of sequential) { // Method One: sequentialObject1[seq] ? sequentialObject1[seq]++ : (sequentialObject1[seq] = 1); // Method Two: sequentialObject2[seq]++ || (sequentialObject2[seq] = 1); } console.log(sequentialObject1); console.log(sequentialObject2);
下面拆解两种方法的底层逻辑:
方法一:三元运算符的隐式布尔转换
三元运算符condition ? expr1 : expr2的核心是判断condition的布尔值:
- 第一次遍历数组元素(比如
"first")时,sequentialObject1["first"]不存在,对应值为undefined。在JavaScript的布尔上下文中,undefined会被隐式转换为false,所以三元运算符执行冒号后的语句,把sequentialObject1["first"]赋值为1。 - 再次遇到相同元素时,
sequentialObject1["first"]的值是数字(比如1),非0数字在布尔上下文中会被转换为true,三元运算符执行前面的sequentialObject1[seq]++,将当前计数加1。
方法二:逻辑或的短路特性 + 自增运算符行为
这里用到了JavaScript逻辑或||的短路求值规则:只要左边表达式的布尔值为true,就不会执行右边的表达式。结合自增运算符的特性拆解:
- 第一次遍历元素时,
sequentialObject2[seq]不存在,值为undefined。执行sequentialObject2[seq]++时,undefined自增会得到NaN,而NaN在布尔上下文中是false。因为左边为false,逻辑或会继续执行右边的语句,把sequentialObject2[seq]赋值为1。 - 再次遇到相同元素时,
sequentialObject2[seq]的值是数字(比如1)。执行sequentialObject2[seq]++时,后置自增运算符会先返回当前值(1),再把数值加1(变成2)。1在布尔上下文中是true,触发逻辑或的短路特性,右边的赋值语句不会执行,最终实现计数加1的效果。
内容的提问来源于stack exchange,提问作者Ameen Shamsan
相关产品推荐
相关产品推荐

