2017-01-17 75 views
0

在我的程序中,使用function()語法返回目標元素的this值,但使用箭頭函數返回窗口對象。這兩個函數中的每一個如何得到他們的this箭頭函數將此作爲窗口對象返回

function editTemplates() { 

//sits within for loop 

    clocksTemplate.gmt[i].addEventListener('keydown', (e) => { 
     console.log(this); //returns window object 
    }); 

    clocksTemplate.gmt[i].addEventListener('keydown', function(e) { 
     console.log(this); //returns element bound to clocksTemplate.gmt 
    }); 

MDN箭頭功能,這應該「保留從封閉的上下文本義」。封閉上下文是事件偵聽器嗎?或者它所在的功能?根據我的測試,箭頭函數的封閉上下文必須是Window對象,但我看不到。使用函數()語法封閉函數是爲了重新定義這個值,我假設它在addEventListener方法中執行。這個主題已被深入討論herehere,但我是一個JS新手,我不明白這是如何適用於我的問題。

+0

箭頭函數將綁定當前作用域的'this',而'addEventListener'將'this'作爲綁定元素 – Rajesh

回答

1

這是完全正常的&箭頭函數的預期行爲。

由於documentation提到了有關常規功能:

每一個新的功能定義在嚴格模式下的函數調用自己的this值(在 情況下,構造一個新的對象,不確定的 上下文對象,如果該函數被稱爲「對象方法」等)。

如果需要覆蓋在常規功能的該值,則不是直接調用它,我們就可以使用call()apply()調用它。

所以對你的日常功能的情況下,回調函數內部得到通過addEventListener使用功能調用的call()apply()這一套以元素勢必clocksTemplate.gmt的價值。使用call()apply()來調用回調是一種標準做法。

在第一個函數(箭頭函數)的情況下,this未被賦值任何新值。由於箭頭函數是匿名的,因此無法使用call()apply()調用它們。所以它繼續具有由封閉函數editTemplates()定義的值,並且恰好是window

請參見下面的代碼示例:

// REGULAR FUNCTION 

function editTemplates() { 

    console.log(this) // window 
    var myVar = this; 

    // sits within for loop 

    clocksTemplate.gmt[i].addEventListener('keydown', function(e) { 

     // new value assigned for 'this' as element bound to clocksTemplate.gmt 

     console.log(this); // returns element bound to clocksTemplate.gmt 

     console.log(myVar); // returns window 
    }); 



// ARROW FUNCTION (Anonymous Functions) 

function editTemplates() { 

    console.log(this) // returns window object 
    var myVar = this; 

    // sits within for loop 

    clocksTemplate.gmt[i].addEventListener('keydown', (e) => { 

     // No new value gets assigned to 'this' 

     console.log(this); // returns window object 

     console.log(myVar); // returns window object 

     // Saves the hassle of saving 'this' to another variable! 
    }); 

希望這回答了你的問題。

+0

你幫我理解了這是如何工作的,謝謝!對於其他人正在研究這個問題,另一種獲取事件目標的方法是使用event.target方法。在上例中,它看起來像這樣: clocksTemplate.gmt [i] .addEventListener('keydown',function(e){console.log(e。目標); }); 這不是我的問題的答案,但只是更多的信息爲未來的人讀這個問題 – kidconcept

+0

很高興我可以幫忙。如果滿意,請接受/提出回答。 –