ES6传播/休息参数未按预期工作

时间:2019-07-18 17:21:27

标签: ecmascript-6

在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 确实包含两个元素;我使用 ... params 将其传递给自定义回调 goPreviousSlide ;但是当到达被调用方(应该以 ... test 接收)时,数组 test 为空。我想念什么?

1 个答案:

答案 0 :(得分:2)

您实际上并没有将参数传递给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");
}