window.apply传递字符串数组仅获首个元素的问题求助
兄弟,我之前踩过一模一样的坑!咱们先抓最核心的问题——apply方法的参数展开特性,这大概率就是你只拿到第一个元素的原因。
问题根源
你在triggerEvents里用了window[command.function].apply(null, command.arguments),这里的apply会把第二个参数(也就是你的字符串数组)拆成单个独立参数传递给目标函数。比如如果command.arguments是["block1", "block2", "block3"],那updateAvailableBlocks实际收到的是3个独立参数:第一个是"block1",第二个是"block2",第三个是"block3"。
但你的updateAvailableBlocks只定义了一个形参args,所以args只会拿到第一个参数"block1",剩下的参数都被忽略了——这就是为什么你只看到首个元素!
两种修复方案
你可以根据自己的需求选其中一种:
方案1:让函数接收完整数组(不展开参数)
修改triggerEvents里的调用方式,把数组作为单个参数传递,而不是展开:
// 用call直接传整个数组作为第一个参数 window[command.function].call(null, command.arguments) // 或者用apply,但把数组包在另一个数组里(让apply只展开一层) window[command.function].apply(null, [command.arguments])
这样updateAvailableBlocks里的args就会是完整的字符串数组了。
方案2:修改函数接收展开后的所有参数
如果你的设计就是要让updateAvailableBlocks接收多个独立参数,那可以用剩余参数语法来把所有参数合并成数组:
function updateAvailableBlocks(...args) { // 用...args接收所有参数为数组 availableBlocks = []; // 这里一定要用let声明i,避免全局变量污染! for(let i=0; i < args.length; i++) { availableBlocks[i] = args[i]; } // 其实更简单的写法:availableBlocks = [...args]; }
或者也可以用arguments对象来获取所有传入的参数(不过剩余参数语法更清晰):
function updateAvailableBlocks() { availableBlocks = []; for(let i=0; i < arguments.length; i++) { availableBlocks[i] = arguments[i]; } }
额外注意点
你的updateAvailableBlocks里的i没有用var/let/const声明,会变成全局变量!如果其他地方也有循环用了全局的i,很可能会导致循环异常,建议加上let声明,避免作用域冲突。
内容的提问来源于stack exchange,提问作者Omnibyte

