# this in arrow function --- ## 什麼是this - 在函式內,this 值取決於如何呼叫該函式[MDN](https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Operators/this) - 如果一個函式是以物件的方法呼叫,它的 this 會被設為該呼叫函式的物件。 --- ## this in Arrow Function - 在過去,函數的 this 變數在不同狀況下一直指向不同值,這樣的特性對物件導向程式設計來說其實相當麻煩。[MDN](https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Functions/Arrow_functions) - 這句話吸引我了,我也覺有點困擾== ---- ### 範例 - 本來想寫一個function,每秒增加一歲, 不是arrow function的寫法 ```JavaScript function Person() { this.age = 0; setInterval(function growUp() { this.age++; // console.log(this.age) }, 1000); } var p = new Person(); //結果setInterval的this是window...@@ ``` [CodePen](https://codepen.io/TengLee/pen/QOJeNx) ---- ### 執行的物件 !== 定義的物件 - 因為它執行的環境會變成是 global environment,因此使用傳統函式時,這個 this 指稱的對象會轉變成 window object 。 - 結果,用這個做法this.age++ 無法每秒加一歲 - 那怎麼辦... ---- ### 使用閉包closure - 利用 closure 將 this 變數存入另一個變數之中 ```JavaScript function correctPerson() { var self = this; self.age = 0; setInterval(function growUp() { console.log("q: " , self) self.age++; }, 1000); } var q = new correctPerson(); ``` ---- ### 主角出場!!! - 也可以用arrow function! ```JavaScript function arrowPerson(){ this.age = 0; setInterval(() => { console.log("r: " , this) this.age++; }, 1000); } var r = new arrowPerson(); ``` - **箭頭函數會自動將 this 變數綁定到其定義時所在的物件**[MDN](https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Functions/Arrow_functions) - 直白一點:箭頭函數當中的 this 是定義時的對象,而不是使用時的對象[PJchen](https://pjchender.blogspot.tw/2017/01/es6-arrow-function.html) ---- ### 你以為這樣就沒事了嗎? - 看下面兩個例子 --- ### this在arrow function要注意的地方之一 <br> ### 例子一 將箭頭函數撰寫為method - arrow function expressions are **best suited for non-method functions**. ~by MDN~ ---- ### 什麼是method function - method 是個屬於object property的function, Methods 跟定義一般function一樣,但他們必須是屬於object的property [MDN](https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Guide/Working_with_Objects) ```JavaScript objectName.methodname = function_name; var myObj = { myMethod: function(params) { // ...do something } }; ``` ---- ```JavaScript var obj = { i: 10, b: function() { console.log(this.i, this); }, c: () => console.log(this.i, this) } obj.b(); // prints 10, obj obj.c(); // prints undefined, window ``` - 這裡的arrow function的this會被定義為global object - arrow functions assume the this of the **lexically enclosing function context**, the this within an object definition is either the window or something else. [stack overflow](https://stackoverflow.com/questions/31095710/methods-in-es6-objects-using-arrow-functions) ---- #### this在arrow function要注意的地方之二 #### 如果定義和呼叫物件不同呢? <br> ## 監聽事件 <br> #### addEventListener ---- ```JavaScript var button = document.querySelector('button'); var fn_arr = () => { // 建立 function 時 this 指 Window console.log(this.constructor.name) // 執行function時 this 指 Window }; var fn = function(){ // 建立 function 時 this 指 Window console.log(this.constructor.name) // 執行function時 this 指 HTMLButtonElement button.addEventListener('click', fn_arr); ``` [JsBin](https://jsbin.com/kotetu/edit?js,output) ---- - 和setTimeout 類似,我們使用的 addEventListener ,也會在整個 execution context 執行結束後,在網頁觸發事件時才執行。 - 函式建立的時間和實際執行的時間是不同的,因此這也創造了兩個不同時間點的 this 所指稱的對象。 --- ## 總結 - 箭頭函式並不是完全只是原本JS中函式的縮寫語法而已,它與原本的函式內部設計有些不同。 - 箭頭函數會自動將 this 變數綁定到其定義時所在的物件 - 在傳統的函數,可以用閉包,var self = this - arrow function的this 不要用在object method - 注意定義的物件和執行的物件有可能會不一樣 - **如果不確定this會指稱到什麼,就console.log出來** --- ### 補充 - 物件裡的值如果是原生值(primitive type;例如,字串、數值、邏輯值),我們會把這個新建立的東西稱為「屬性(property)」;如果物件裡面的值是函式(function)的話,我們則會把這個新建立的東西稱為「方法(method)」。[PJchen](https://pjchender.blogspot.tw/2016/03/javascriptthisbug.html) - [談談JavaScript中的"this"和它的bug](https://pjchender.blogspot.tw/2016/03/javascriptthisbug.html) - The most common use case for arrow functions is as short "lambdas" which do not redefine this, often used when passing a function as a callback to some function. [stack overflow](https://stackoverflow.com/questions/31095710/methods-in-es6-objects-using-arrow-functions)
{"metaMigratedAt":"2023-06-14T15:08:20.169Z","metaMigratedFrom":"Content","title":"this in arrow function","breaks":true,"contributors":"[]"}
    784 views