5 回答

TA贡献1841条经验 获得超3个赞
addEventListener 需要一个函数作为事件处理程序的第二个参数(回调)。
第一个场景你传递给它一个命名函数引用。这就像代表函数对象的变量
如果你这样做:
addEventListener('click', myFunc()) // with ()
然后该函数将立即被调用,并且需要返回另一个函数,该函数将在事件发生时被调用。
在第二种情况下,回调函数是一个匿名函数,它将在事件发生时被调用。当它被调用时,它调用内部函数
不同之处在于第一种情况,您的命名函数将事件对象作为第一个参数,而上下文this将是元素。
第二种情况的上下文this是你的类,而不是元素,如果你想访问事件对象,你需要自己传递它
简单例子
document.getElementById('1').addEventListener('click', myFunc)
document.getElementById('2').addEventListener('click', (evt)=> myFunc(evt))
document.getElementById('3').addEventListener('click', ()=> myFunc())
function myFunc(event){
console.clear()
if(event){
console.log('Type of event:', event.type);
}else{
console.log('No event object')
}
if(this instanceof HTMLElement){
console.log('"this" is element:', this.tagName)
}else{
console.log('"this" is your class')
}
}
<button id="1">Named function</button>
<button id="2">Anonymous with evt</button>
<button id="3">Anonymous no evt</button>

TA贡献1816条经验 获得超4个赞
选项一
cartLogic() {
clearCartBtn.addEventListener('click', this.clearCart);
}
这里的第二个参数是传递给 的事件处理程序,它addEventListener没有括号,因为您作为参数传递的函数已经存在于该cartLogic函数所附加的对象上。因此,当您使用时,this.clearCart您指的cartLogic是函数附加到的对象以及另一个名为clearCart.
方案二
cartLogic() {
clearCartBtn.addEventListener('click', () => {
this.clearCart();
})
}
在这里,您传递了一个带有箭头函数表达式的匿名函数定义。
根据定义,addEventListener期望作为参数
type:一个区分大小写的字符串,表示要侦听的事件类型。
listener指定类型的事件发生时接收通知的对象(实现Event接口的对象)。这必须是实现 EventListener 接口的对象或 JavaScript 函数。有关回调本身的详细信息,请参阅事件侦听器回调。
您可以了解有关addEventListener 的所有参数的更多信息。

TA贡献1818条经验 获得超8个赞
为清楚起见,您的第二个示例应重写为:
cartLogic() {
clearCartBtn.addEventListener('click', () => this.clearCart());
}
现在,如果您从示例中删除除差异之外的所有内容,将很容易理解它们的不同之处。
this.clearCart
() => this.clearCart()
第一个例子是函数this.clearCart.
第二个例子是一个函数,它执行函数this.clearCart.
第二个例子涉及不必要的间接。这是唯一的区别。您不是直接传递this.clearCart(如第一个示例),而是传递一个唯一目的是执行的不同函数this.clearCart。

TA贡献1818条经验 获得超3个赞
选项1. -> 这里我们不能使用括号,因为它是回调函数的引用,如果你在这里添加括号,该函数将立即被调用。
cartLogic() {
clearCartBtn.addEventListener('click', this.clearCart);
}
选项 2.-> 在这里你定义了一个匿名函数,所以它将作为回调函数工作,并且在这个函数中将this.clearCart();被调用。
cartLogic() {
clearCartBtn.addEventListener('click', () => {
this.clearCart();
})
}

TA贡献1884条经验 获得超4个赞
因此,为了简化您的问题,您想知道使用带括号和不带括号的函数有什么区别。
假设我们有一个logText()看起来像这样的函数
function logText() {
console.log("Hello world!")
}
然后我们像这样在控制台中运行
logText()
我们收到这个发回
"Hello world!"
现在当我们在控制台中执行此操作时
logText
我们取回对函数的引用,如下所示
ƒ logText() {
console.log("Hello world!")
}
ƒ → 功能
这有什么区别
cartLogic() {
clearCartBtn.addEventListener('click', this.clearCart);
}
和
cartLogic() {
clearCartBtn.addEventListener('click', () => {
this.clearCart()
});
}
它们之间最大的区别是第一个例子clearCart()被立即调用,而第二个例子被包裹在一个匿名函数中并且clearCart()没有被立即调用。
这会改变事情的运作方式吗?
好吧,不是真的,一切仍然会以相同的方式工作,但为什么你不必在末尾添加 paratheneseclearCart因为这是引用函数所以我们可以想到:
cartLogic() {
clearCartBtn.addEventListener('click', this.clearCart);
}
作为
cartLogic() {
clearCartBtn.addEventListener('click', () => {
// All code for your function
...
});
}
但这对我们在函数(在本例中addEventListener())将一些值发送回回调时的编码方式产生了影响,在这种情况下,很可能是事件 (e) 被发送回回调。
假设您clearCart()有一个名为“e”或“event”的参数,如果我们使用您的第一个示例,我们不必自行处理e/event或解析事件,它将为我们解析,但是对于您的借调示例,您将不得不做这样的事情:
cartLogic() {
clearCartBtn.addEventListener('click', e => {
this.clearCart(e)
});
}
为什么第二个例子没有括号就不能工作?
因为就像我在回答的前面所说的那样,不带括号的函数是对函数的引用,而带括号的函数将运行。
当我们不想调用函数而是想传递函数的引用时,我们使用不带括号的函数。
例如:
logText.length
这是解析函数对length方法的引用。
length用在函数上将返回函数期望的参数数量。
这已经很长了,所以我现在就在这里结束如果有什么我没有说或没有说好的发表评论,我会添加它:)
还看到了对其他人关于上下文的回答的评论this,我认为这与此无关,更多的是关于你如何声明函数() => {}或function () {}.
添加回答
举报