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 () {}.
添加回答
舉報