使用switch(true)与Array.concat()的代码运行异常,求原因分析
为什么使用
switch(true)合并数组时原代码无法正确更新数组? 我知道switch(true)相比if-else-if序列的优势之一是可以省略break来执行多个代码块,于是尝试用这种方式合并多个数组,但这段简单的代码运行异常。下面是我的原代码和正确代码示例,恳请大家解释switch(true)部分的问题所在!
原代码
function concatArrays() { var recentlyCompleted = ["rc1", "rc2"]; var upcomingActivities = []; var decisionsRequired = []; var records = []; switch(true) { case (recentlyCompleted.length >0): records.concat(recentlyCompleted); console.log("recentlyCompleted.length >0"); console.log(records); case (upcomingActivities.length >0): records.concat(upcomingActivities); console.log("upcomingActivities.length >0"); console.log(records); case (decisionsRequired.length >0): records.concat(decisionsRequired); console.log("decisionsRequired.length >0"); console.log(records); break; } document.getElementById("demo").innerHTML = JSON.stringify(records); var records2 = recentlyCompleted.concat(upcomingActivities).concat(decisionsRequired); document.getElementById("demo2").innerHTML = JSON.stringify(records2); }
<head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width"> <title>switch(true)</title> </head> <body> <p>Click the button to join arrays.</p> <button onclick="concatArrays()">Try it</button> <p id="demo"></p> <p id="demo2"></p> </body>
正确代码示例
function concatArrays() { var recentlyCompleted = ["rc1", "rc2"]; var upcomingActivities = []; var decisionsRequired = []; var records = []; switch (true) { case (recentlyCompleted.length > 0): records = records.concat(recentlyCompleted); console.log("recentlyCompleted.length >0"); console.log(records); case (upcomingActivities.length > 0): records = records.concat(upcomingActivities); console.log("upcomingActivities.length >0"); console.log(records); case (decisionsRequired.length > 0): records = records.concat(decisionsRequired); console.log("decisionsRequired.length >0"); console.log(records); break; } document.getElementById("demo").innerHTML = JSON.stringify(records); var records2 = recentlyCompleted .concat(upcomingActivities) .concat(decisionsRequired); document.getElementById("demo2").innerHTML = JSON.stringify(records2); }
问题解析
其实你的switch(true)逻辑本身是没问题的——你利用了switch的贯穿(fall-through)特性:当匹配到第一个true的case后,因为没有break,代码会继续执行后续所有case直到遇到break,这正是你想要的依次合并数组的效果。
真正的问题出在**Array.concat()方法的使用上**:
concat()是一个纯方法,它不会修改调用它的原数组,而是返回一个包含合并结果的新数组。- 原代码中你只是调用了
records.concat(recentlyCompleted),但没有把返回的新数组赋值回records,所以records始终是初始的空数组[]。 - 正确代码中使用了
records = records.concat(...),把每次合并后的新数组重新赋值给records,这样才真正更新了这个数组的内容。
举个简单的例子直观理解:
let arr = []; arr.concat([1,2]); // 这行返回[1,2],但arr还是[] arr = arr.concat([1,2]); // 现在arr变成了[1,2]
另外补充一点:即使后续的数组(比如upcomingActivities)为空,concat()也不会有问题——它会直接返回原数组,所以你的switch贯穿逻辑可以正常处理空数组的情况,不需要额外判断。
总结一下:你的switch(true)用法是正确的,问题完全是因为忽略了concat()的返回值特性,没有对原数组进行重新赋值导致的。
内容的提问来源于stack exchange,提问作者Alex Pilugin
相关产品推荐
相关产品推荐

