JavaScript中一行代码添加元素/创建列表失败问题排查
为什么一行写法无法正确更新bucket?
核心问题很简单:Array.push()方法返回的是数组更新后的长度(数字),而不是修改后的数组本身。
两种写法的具体差异
正确写法的逻辑
for (let [num, freq] of map) { let values = (bucket[freq] || new Array()) ; values.push(num); bucket[freq] = values }
- 先拿到目标数组:如果
bucket[freq]已经是数组就用它,否则新建空数组,把这个数组赋值给values; - 调用
values.push(num):这一步会直接修改values指向的数组(往里面加元素),而push返回的是数组的新长度(比如第一次加元素返回1),但我们根本没用到这个返回值; - 最后把已经加了新元素的数组重新赋值给
bucket[freq],所以最终bucket[freq]存的是正确的数组。
错误写法的问题
for (let [num, freq] of map) { bucket[freq] = (bucket[freq] || new Array()).push(num) ; }
这里你把push(num)的返回值(也就是数组长度数字)直接赋值给了bucket[freq]。比如第一次执行后,bucket[freq]会变成1,第二次变成2,完全不是你想要的数组。后续再操作这个位置时,自然会出错。
可以正常运行的一行写法
如果想简化成一行,有两种靠谱的方式:
- 先确保数组存在,再执行push(推荐,和原写法逻辑一致,修改原数组):
for (let [num, freq] of map) { (bucket[freq] ??= []).push(num); }
??=是空值赋值运算符,只有当bucket[freq]是undefined或null时,才会把空数组赋值给它,之后直接对这个数组调用push,不会覆盖成数字。
- 使用
concat返回新数组(会创建新数组,不修改原数组):
for (let [num, freq] of map) { bucket[freq] = (bucket[freq] || []).concat(num); }
内容的提问来源于stack exchange,提问作者JohhnyM
相关产品推荐
相关产品推荐

