这两种在 addEventListener 中使用回调的方式有什么区别?
What's the difference between these 2 ways of using a callback in addEventListener?
我在 addEventListener
中找到了两种使用回调函数的方法,但对每种方法的作用感到困惑。
- 第一个选项为什么不用括号呢?在第二个选项中我们使用它;有什么区别?
cartLogic
和 clearCart
都是 class 的一部分。我确实通过了 MDN,但找不到明确的答案。
请详细说明。
选项 1:
cartLogic() {
clearCartBtn.addEventListener('click', this.clearCart);
}
选项 2:
cartLogic() {
clearCartBtn.addEventListener('click', () => {
this.clearCart();
})
}
方案1.->这里不能使用括号,因为是回调函数的引用,如果在这里加括号,函数会立即被调用。
cartLogic() {
clearCartBtn.addEventListener('click', this.clearCart);
}
选项 2.-> 此处您定义了一个匿名函数,因此它将作为回调函数工作,并且在该函数内部将调用函数 this.clearCart();
。
cartLogic() {
clearCartBtn.addEventListener('click', () => {
this.clearCart();
})
}
选项一
cartLogic() {
clearCartBtn.addEventListener('click', this.clearCart);
}
这里的第二个参数是传递给 addEventListener
的事件处理程序,它没有括号,因为您作为参数传递的函数已经存在于 [=13= 所在的对象上] 函数附加到。因此,当您使用 this.clearCart
时,您指的是附加了 cartLogic
函数的对象,以及另一个名为 clearCart
.
的方法
选项二
cartLogic() {
clearCartBtn.addEventListener('click', () => {
this.clearCart();
})
}
这里你传递了一个用 arrow function expression 定义的匿名函数。
根据定义,addEventListener 期望作为参数
type: A case-sensitive string representing the event type to listen for.
listener The object that receives a notification (an object that implements the Event interface) when an event of the specified type occurs. This must be an object implementing the EventListener interface, or a JavaScript function. See The event listener callback for details on the callback itself.
您可以了解有关 addEventListener 的所有论点的更多信息。
addEventListener 需要一个函数作为事件处理程序的第二个参数(回调)。
第一个场景你传递给它一个命名函数引用。这就像代表函数对象的变量
如果你这样做:
addEventListener('click', myFunc()) // with ()
然后该函数将立即被调用,并且需要 return 另一个在事件发生时被调用的函数。
在第二种情况下,回调函数是一个匿名函数,它将在事件发生时被调用。当它被调用时,它会调用内部函数
区别在于第一种情况,您的命名函数将事件对象作为第一个参数,this
的上下文将是元素。
第二种情况下 this
的上下文将是你的 class,而不是元素,如果你想访问事件对象,你需要自己传递它
简单示例
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>
为清楚起见,您的第二个示例应重写为:
cartLogic() {
clearCartBtn.addEventListener('click', () => this.clearCart());
}
现在,如果您从示例中删除除差异之外的所有内容,将很容易理解它们的不同之处。
this.clearCart
() => this.clearCart()
第一个例子是函数,this.clearCart
。
第二个例子是执行函数的函数,this.clearCart
.
第二个示例涉及不必要的间接寻址。这是唯一的区别。您不是直接传递 this.clearCart
(如第一个示例),而是传递一个不同的函数,其唯一目的是执行 this.clearCart
.
因此,为了简化您的问题,您想知道使用带括号和不带括号的函数有什么区别。
假设我们有一个函数 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()
没有被立即调用。
这会改变事情的运作方式吗?
不是真的,一切仍然会以相同的方式工作,但为什么你不必在 clearCart
的末尾添加 parathenese 因为这是引用函数所以我们可以想到:
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
用于函数将 return 函数期望的参数数量。
这篇文章很长,所以我会在这里结束如果有什么我没有说或没有说好的留下评论,我会添加它:)
还看到了对其他人关于 this
上下文的回答的评论,在我看来,这与此并没有真正的关系,更多的是关于你如何声明函数 () => {}
或 function () {}
.
我在 addEventListener
中找到了两种使用回调函数的方法,但对每种方法的作用感到困惑。
- 第一个选项为什么不用括号呢?在第二个选项中我们使用它;有什么区别?
cartLogic
和 clearCart
都是 class 的一部分。我确实通过了 MDN,但找不到明确的答案。
请详细说明。
选项 1:
cartLogic() {
clearCartBtn.addEventListener('click', this.clearCart);
}
选项 2:
cartLogic() {
clearCartBtn.addEventListener('click', () => {
this.clearCart();
})
}
方案1.->这里不能使用括号,因为是回调函数的引用,如果在这里加括号,函数会立即被调用。
cartLogic() {
clearCartBtn.addEventListener('click', this.clearCart);
}
选项 2.-> 此处您定义了一个匿名函数,因此它将作为回调函数工作,并且在该函数内部将调用函数 this.clearCart();
。
cartLogic() {
clearCartBtn.addEventListener('click', () => {
this.clearCart();
})
}
选项一
cartLogic() {
clearCartBtn.addEventListener('click', this.clearCart);
}
这里的第二个参数是传递给 addEventListener
的事件处理程序,它没有括号,因为您作为参数传递的函数已经存在于 [=13= 所在的对象上] 函数附加到。因此,当您使用 this.clearCart
时,您指的是附加了 cartLogic
函数的对象,以及另一个名为 clearCart
.
选项二
cartLogic() {
clearCartBtn.addEventListener('click', () => {
this.clearCart();
})
}
这里你传递了一个用 arrow function expression 定义的匿名函数。
根据定义,addEventListener 期望作为参数
type: A case-sensitive string representing the event type to listen for.
listener The object that receives a notification (an object that implements the Event interface) when an event of the specified type occurs. This must be an object implementing the EventListener interface, or a JavaScript function. See The event listener callback for details on the callback itself.
您可以了解有关 addEventListener 的所有论点的更多信息。
addEventListener 需要一个函数作为事件处理程序的第二个参数(回调)。
第一个场景你传递给它一个命名函数引用。这就像代表函数对象的变量
如果你这样做:
addEventListener('click', myFunc()) // with ()
然后该函数将立即被调用,并且需要 return 另一个在事件发生时被调用的函数。
在第二种情况下,回调函数是一个匿名函数,它将在事件发生时被调用。当它被调用时,它会调用内部函数
区别在于第一种情况,您的命名函数将事件对象作为第一个参数,this
的上下文将是元素。
第二种情况下 this
的上下文将是你的 class,而不是元素,如果你想访问事件对象,你需要自己传递它
简单示例
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>
为清楚起见,您的第二个示例应重写为:
cartLogic() {
clearCartBtn.addEventListener('click', () => this.clearCart());
}
现在,如果您从示例中删除除差异之外的所有内容,将很容易理解它们的不同之处。
this.clearCart
() => this.clearCart()
第一个例子是函数,this.clearCart
。
第二个例子是执行函数的函数,this.clearCart
.
第二个示例涉及不必要的间接寻址。这是唯一的区别。您不是直接传递 this.clearCart
(如第一个示例),而是传递一个不同的函数,其唯一目的是执行 this.clearCart
.
因此,为了简化您的问题,您想知道使用带括号和不带括号的函数有什么区别。
假设我们有一个函数 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()
没有被立即调用。
这会改变事情的运作方式吗?
不是真的,一切仍然会以相同的方式工作,但为什么你不必在 clearCart
的末尾添加 parathenese 因为这是引用函数所以我们可以想到:
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
用于函数将 return 函数期望的参数数量。
这篇文章很长,所以我会在这里结束如果有什么我没有说或没有说好的留下评论,我会添加它:)
还看到了对其他人关于 this
上下文的回答的评论,在我看来,这与此并没有真正的关系,更多的是关于你如何声明函数 () => {}
或 function () {}
.