为什么在传递参数时必须在addeventlistener中有一个匿名函数?

时间:2015-04-02 22:51:12

标签: javascript

因此,如果你有一个带参数的命名函数并调用该函数,那么在使用addEventListener时它无法正常工作,但是如果你将它包装在一个匿名函数中,那么它是否有效,为什么会这样?

<input type="button" value="click me" id="subBtn" /> <br />
<div id="myDiv">default text</div>

这是我的JavaScript。

function myFunc(str){
   document.getElementById("myDiv").innerHTML = str;
}

//does not work.
document.getElementById("subBtn").addEventListener("click", myFunc("hey there buddy"), false);

//this works, but why?
document.getElementById("subBtn").addEventListener("click", function(){
   myFunc("hey there buddy");
}, false);

现在,如果myFunc没有采用任何参数,那么两种方式都可以。

2 个答案:

答案 0 :(得分:2)

您必须将函数作为参数传递给addEventListener

但是,它不必是匿名的:

element.addEventListener("click", function IAmNotAnonymous(){
   myFunc("hey there buddy");
});

你可以使用函数调用,而不需要函数表达式包装器。但是,该调用中返回的值必须是函数:

function myFunc2(arg) {
    return someFunction; // <-- This must be a function
}
element.addEventListener("click", myFunc2("hey there buddy"));

当您使用addEventListener("click", myFunc("hey there buddy"))时,它不起作用,因为您的myFunc没有返回功能。取而代之的是,

  • 您正在呼叫myFunc,而不是等待事件
  • 您将返回的值(undefined)作为参数传递给addEventListener

请注意,此问题不是由于有参数,而是由于调用该函数。使用addEventListener("click", myFunc())将是相同的。

您可能对bind

感兴趣,而不是使用函数表达式包装器
element.addEventListener("click", myFunc.bind(void 0, "hey there buddy"));

答案 1 :(得分:2)

这是有效的原因:

function(){
   //code here
  }

这是一个函数声明,在click事件发生之前不会被触发。这是一样的:

var foo = function(){
  //code here
};

element.addEventListener('click', foo, false);

但是现在你遇到了没有参数的问题,因为它们只在实际触发函数时粘贴。该操作隐藏在addEventListener内,无法直接访问。

话虽如此,使用.bind

有一个简单的解决方法
element.addEventListener('click', myFunc.bind(null, 'Hey there buddy'), false);

什么绑定会创建一个具有绑定范围的函数(第一个参数,这可能非常有用)和参数(后面的每个参数)。

这有效地将绑定参数传递给您的命名函数,而不使用匿名包装器。