为什么不能直接使用addEventListener传递参数?

3
我理解您无法将任何参数传递给addEventListener。您必须这样做。
el.addEventListener("click", function(){callSomeFunction("myString");}, false);

“但是为什么要让我们以这种方式做呢?”

1
如果您想知道为什么不能像setTimeoutsetInterval那样指定其他参数,那很可能是因为监听器已经接收到一个event参数。如果您指定自己的参数,它会如何运作? - canon
2
请问您能否提供一个示例,说明如何绑定带有附加参数的事件处理程序? - Felix Kling
2
@thomas el.addEventListener("click", myFunc.bind(el,1,2,3), false); - Ian
2
@Ian:在这种情况下(以及你的例子中),事件对象将作为第四个参数传递。快速示例:var a = function() { console.log(arguments); }.bind(null, 1); a(2);(显示 [1,2])。 - Felix Kling
@FelixKling 真的吗?有趣。 - Ian
显示剩余6条评论
2个回答

6

因为如果您这样做:

el.addEventListener("click", callSomeFunction("myString"), false);

它会立即执行callSomeFunction,然后将其返回值传递给addEventListener,然后再使用它。

例如,如果我有这个:

function callSomeFunction() {
  doSomeThings();
  return 10;
}

那么 el.addEventListener("click", callSomeFunction("myString"), false); 实际上会调用 el.addEventListener("click", 10, false);

如果你有一个没有参数的函数,你可以直接传递它:

el.addEventListener("click", callSomeFunction, false);

@FelixKling 这是有效的JS吗?我非常确定addEventListener只需要3个参数,但我可能错了。 - tckmn
1
@thomas:你认为函数通常是如何处理的? - Felix Kling
通过能够将任意数量的参数传递给函数,@FelixKling 可以实现此功能。 - 1252748
2
@thomas:也许让你困惑的是,你传递给 addEventListener 的函数不是由 调用的。当事件发生时,引擎会调用该函数,并且该函数被调用的方式只向其传递一个参数,即事件对象。你无法影响这一点,因为你无法控制代码。每当你使用外部/本地库/接口时,这总是发生的情况。 - Felix Kling
1
@thomas:你的意思是 function() { theFunction("string1", "string2", false"); } 吗?因为在这种情况下,function() { ... } 是一个函数表达式,它创建了一个新的函数对象。它不会调用函数,而是定义了一个函数。我将在此重复我的另一条评论中的示例:如果你有 foo(bar()),那么 bar 将首先被执行,并且返回值将传递给 foo。这就是参数解析的工作原理,对于 addEventListener 也是如此。此外,如果 foo 预期一个函数引用(即 foo(bar)),那么你无法控制 foo 如何调用 bar - Felix Kling
显示剩余11条评论

3

addEventListener 必须将函数对象作为其第二个参数,但没有理由该函数对象不能由 另一个函数 生成。也许您会对生成函数的高阶函数感兴趣:

function generateAlertFunc(alertString) {
    return function() {
        alert(alertString);
    }
}

el.addEventListener("click", generateAlertFunc("myString"), false);

generateAlertFunc函数接受参数并使用它们构建一个新函数,该函数被传递到addEventListener中。


好的。所以我想我错了。我以为你做不到这个。 - 1252748
@thomas 当然可以 - 关键是 addEventListener 需要一个函数引用作为其第二个参数。调用 generateAlertFunc 返回一个 函数,因此它可以正常工作。 - Ian
@thomas 是的,setTimeout 也是一样 - 它期望一个函数引用,所以您可以采取相同的方法,或者像您刚才看到的那样使用.bind() - Ian
@thomas 函数只是对象。任何接受回调函数(setTimeoutaddEventListener等)的函数都期望一个函数对象。您可以以任何喜欢的方式生成和引用该函数对象(例如,作为另一个函数的返回值,作为匿名文字,在变量中存储等)。 - apsillers
有趣的解决方案。在其他不是 addEventListener 的调用中,generateAlertFunc(alertString) 仍然可以工作。 - user1934286

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接