首页 > 解决方案 > ES6 传播/休息参数未按预期工作

问题描述

在 Javascript 中,我创建了一个函数activateClickable来封装回调的分配,该回调分配给单击和使用回车键或空格键的元素,例如带有 tabindex 的元素。我将其设置为允许提供可选参数,以防回调接受参数。

我通过让轮播上的上一个箭头的单击侦听器接收参数“Foo”和“Bar”来对此进行测试;照顾一些初步的逻辑;然后将参数params传递给回调函数goPreviousSlide

function goPreviousSlide(...test) {
    console.log("Test");
    console.log(test);
    alert("This will go to the previous slide.");
}

function goNextSlide() {
    alert("This will go to the next slide.");
}

function attachListeners() {
    activateClickable("carousel-previous-arrow", function() { goPreviousSlide(); }, "Foo", "Bar");
    activateClickable("carousel-next-arrow", function() { goNextSlide(); });
}

function activateClickable(className, callback, ...params) {
    Array.from(document.getElementsByClassName(className)).forEach(function(elem) {
        elem.addEventListener("click", function(event) {
            event.preventDefault();
            console.log("Hello");
            console.log(params);
            callback(...params);
        });
        elem.addEventListener("keyup", function(event) {
            if (event.keyCode === 13 || event.keyCode === 32) { // Enter or spacebar
                event.preventDefault();
                callback(...params);
            }
        });
    });
}

当我单击上一个箭头时,我希望在 Chrome 中看到的是

Hello
> (2) ["Foo", "Bar"]
Test
> (2) ["Foo", "Bar"]

我得到的是

Hello
> (2) ["Foo", "Bar"]
Test
> []

Edge 中的结果类似:

Hello
> [object Array]: ["Foo", "Bar"]
Test
> [object Array]: []

换句话说,当我在点击处理程序中时,我看到params确实有两个元素;我将它传递给自定义回调,goPreviousSlide使用...params;但是当它到达被调用者时,它应该作为...test接收它,数组test是空的。我错过了什么?

标签: ecmascript-6

解决方案


您实际上并没有将参数传递给,goPreviousSlide因为您goPreviousSlide()在没有参数的情况下调用内部回调:

function() { goPreviousSlide(); }, "Foo", "Bar")
  //Called Here ------------^

当您使用参数调用回调时,您不是在调用 `goPreviousSlide(),而是在调用这个不带参数的函数:

function() { goPreviousSlide(); }

也许您只想goPreviousSlide单独作为回调传递:

activateClickable("carousel-previous-arrow", goPreviousSlide, "Foo", "Bar");

然后,当您调用回调时,您可以传递参数。

或者,您可以在回调中接受参数并将它们转发到:

function attachListeners() {
    activateClickable("carousel-previous-arrow", function(...params) { goPreviousSlide(...params); }, "Foo", "Bar");
}

推荐阅读