JS数组reduce方法执行时布尔值被追加到当前值的原因是什么?
问题原因解析
1. 表达式返回false、true、true的原因
核心是运算符优先级问题:===的优先级高于+=,且逻辑与&&会短路执行。
你写的(arr[i] += arr[i - 1] === 'VI') && i != 0执行顺序如下:
- 第一次迭代i=0:先执行括号内逻辑,
arr[i-1]为undefined,和'VI'全等比较结果为false,执行arr[0] += false得到字符串'Ifalse',然后执行&& i != 0,i=0不满足,整个表达式结果为false - 第二次迭代i=1:
arr[i-1]是第一次修改后的'Ifalse',和'VI'比较结果为false,执行arr[1] += false得到字符串'Ifalse'(非空字符串布尔值为true),&& i !=0满足,整个表达式结果为true - 第三次迭代i=2:逻辑和第二次一致,
arr[i-1]依旧不等于'VI',执行赋值后得到的字符串为真值,i不为0,整个表达式结果为true
2. curr值变为Ifalse的原因
你在表达式中使用+=直接修改了reduce遍历的原数组的元素,布尔值false在和字符串拼接时会自动转为字符串'false',因此每个数组元素都会被拼接上'false'后缀。又因为reduce迭代时直接读取原数组的最新值,所以后续迭代的curr就变成了带false后缀的字符串。
修正方案
你的核心需求是判断当前值与前一个值的组合是否等于'VI',不需要修改原数组,直接拼接两个字符做比较即可,同时要先判断下标合法性避免越界:
var romanToInt = function (s) { const DICT = { I: 1, V: 5, X: 10, L: 50, C: 100, D: 500, M: 1000, } let reversedArr = s.split('').reverse() return reversedArr.reduce((sum, cur, i, arr) => { let value = DICT[cur] // 先判断下标合法,再拼接字符比较 if (i !== 0 && arr[i] + arr[i - 1] === 'VI') { sum -= value } else { sum += value } return sum }, 0) } console.log(romanToInt('III')) // 输出3
修正点说明
- 删除了原逻辑中对数组元素的赋值操作,避免篡改原数组导致后续迭代异常
- 调整判断顺序:先判断
i !== 0,避免访问arr[-1]出现异常 - 直接拼接
arr[i]和arr[i-1]后和'VI'做全等比较,逻辑符合需求
内容的提问来源于stack exchange,提问作者Tyler Morales
相关产品推荐
相关产品推荐

