2016-08-14 55 views
1

我無法理解爲什麼在以下示例中創建的「重複」事件偵聽器的行爲如此不同。我已經仔細閱讀了幾個有關該主題的討論,但我剛剛開始學習JavaScript,並且我無法弄清楚版本2中發生的事情在版本1中是不會發生的。是否有人願意爲我提供啓發?何時丟棄重複事件偵聽器,以及它們何時不是?

這是JSFiddle demo。 JavaScript看起來像這樣:

// VERSION 1 

    var clickEvents = 0; 

    button.addEventListener('click', buttonFunction); 

    function buttonFunction() { 
    clickEvents++; 
    display.innerHTML = clickEvents; // <-- increases incrementally 
    button.addEventListener('click', buttonFunction); 
    } 

// VERSION 2 

    var clickEvents = 0; 

    mainFunction(); 

    function mainFunction() { 

    button.addEventListener('click', buttonFunction); 

    function buttonFunction() { 
     clickEvents++; 
     display.innerHTML = clickEvents; // <-- increases exponentially 
     mainFunction(); 
     } 
    } 

回答

0

該行爲是由於範圍確定。在版本1中,您將添加全局範圍的函數。當您嘗試再次添加它時,它會靜默失敗,因爲該功能已被註冊。從MDN:

多個相同的事件偵聽器

如果多個相同的事件偵聽器註冊到同一事件目標 使用相同的參數,重複的情況下被丟棄。它們不是 會導致EventListener被調用兩次,並且不需要使用removeEventListener方法手動刪除 。

在2版,因爲裏面宣佈將mainFunctionbuttonFunction局部範圍mainFunction你會得到一個不同的版本,因爲範圍變化是不一樣的全局函數和每個調用它。由於JS引擎在調用addEventListener時認爲函數不同,因此每個函數都是獨立添加的。每次點擊按鈕時,您都會將附加到按鈕的偵聽器數量加倍。

的片段演示了JS引擎認爲的bar()每次調用有不同的地方foo

function foo() { 
 
    console.log("global"); 
 
} 
 

 
function bar() { 
 
    function foo() { 
 
\t  console.log("local"); 
 
    } 
 
    return foo; 
 
} 
 

 
var oneG = foo; 
 
var twoG = foo; 
 
var oneL = bar(); 
 
var twoL = bar(); 
 

 
console.log(`Global: ${oneG === twoG}`); 
 
console.log(`Local: ${oneL === twoL}`);

相關問題