JavaScript三元运算符使用问题:字符统计逻辑异常排查
为什么用三元运算符统计字符出现次数时结果不符合预期?
我最近在写一个统计字符串字符出现次数的功能,用if/else实现的时候完全正常:
const string = "Hello world"; const chars = {}; for(let char of string) { if(!chars[char]) chars[char] = 1; else chars[char]++; } console.log(chars); // { H: 1, e: 1, l: 3, o: 2, ' ': 1, w: 1, r: 1, d: 1 }
但换成三元运算符之后,输出就不对了,每个重复的字符只统计了1次:
const string = "Hello world"; const chars = {}; for(let char of string) { chars[char] = !chars[char] ? 1 : chars[char]++; } console.log(chars); // { H: 1, e: 1, l: 1, o: 1, ' ': 1, w: 1, r: 1, d: 1 }
这到底是哪里出问题了?
问题根源:后自增运算符的返回值特性
这里的核心问题是**chars[char]++的返回值是自增前的原始值**,而不是自增后的值。
当你用三元运算符赋值时,咱们拿重复出现的l来举例:
- 第一次遇到
l时,chars['l']不存在,走1的分支,赋值后chars['l'] = 1。 - 第二次遇到
l时,!chars['l']是false,走冒号后面的分支:chars['l']++。这个操作会先返回当前值1,再把chars['l']变成2。但紧接着你又把这个返回值1赋值回给了chars['l']——相当于把刚刚自增的结果又覆盖掉了!
所以每次重复遇到同一个字符时,都会先自增,然后立刻打回原形,最终结果永远是1。
修正方案
有两种简单的方式修复这个问题:
- 改用前自增运算符:
++chars[char]会先完成自增,再返回自增后的值,这样赋值的就是正确结果:
chars[char] = !chars[char] ? 1 : ++chars[char];
- 直接简化逻辑:其实不需要三元运算符,用短路求值或者更简洁的写法也能搞定:
// 方式一:短路求值 chars[char] = (chars[char] || 0) + 1; // 方式二:空值合并赋值+自增 chars[char] ??= 0; chars[char]++;
这两种写法都能正确统计每个字符的出现次数,结果和if/else版本完全一致。
内容的提问来源于stack exchange,提问作者Prem
相关产品推荐
相关产品推荐

