2021年12月31日 JavaScript (JS Primer) 関数とthis
Arrow Functionとthis
- Arrow Functionで定義された関数やメソッドにおける
this
がどの値を参照するかは定義時(静的)に決まります。 - 一方、Arrow Functionではないfunctionキーワードの関数においては、
this
は呼び出し元に依存するため関数の実行時(動的)にthisの値が決まります。
Arrow Function内では、暗黙的な引数は受け付けられないため、thisが定義されません。
このときのthisは外側のスコープ(関数)のthisを参照します。
thisはECMAScriptのキーワードであるため、thisという変数を定義できません。
通常の変数と同様にthisがどの値を参照するかは静的(定義時)に決定されます。(静的スコープ)
つまり、Arrow Functionにおけるthisは「Arrow Function自身の外側のスコープに定義されたもっとも近い関数のthisの値」となります。
以下の例はfn関数の外側には関数がないためトップレベルのthisを参照して返していることを示しています。厳密等価演算子でthisと合致させていることで証明されています。
const fn = () => { // この関数の外側には関数は存在しない // トップレベルの`this`と同じ値 return this; }; console.log(fn() === this); fn() 出力結果 true [object Window] // thisのトップレベルであるwindowを参照
thisの値は、実行コンテキストが"Script"ならばグローバルオブジェクト(window)となり、"Module"ならばundefinedとなります。
以下のouter関数はthisを返すArrow Functionをreturnします。
この場合、outer関数のthisを参照するためundefinedとなります。
(outerは関数宣言であるため)
"use strict"; function outer() { // Arrow Functionで定義した関数を返す return () => { // この関数の外側には`outer`関数が存在する // `outer`関数に`this`を書いた場合と同じ return this; }; } // `outer`関数の返り値はArrow Functionにて定義された関数 const innerArrowFunction = outer(); console.log(innerArrowFunction()); // => undefined
復習
- 関数呼び出し時に呼び出し元のスコープの変数を参照する仕組みを動的スコープといいます。
- オブジェクトのプロパティが関数である場合、それをメソッドといいます。
Arrow Functionにthisを使えるのはメソッドだからという基本的なところをもう一度復習しました。
また、一つ上のコードブロックで結果がundefinedになるのはfunction宣言のスコープにthisが参照しにいっているからというのも以下の表から復習できました。
名前 | 関数 | メソッド |
---|---|---|
関数宣言( function fn(){} ) | ⭕️ | ❌ |
関数式( const fn = function(){} ) | ⭕️ | ⭕️ |
Arrow Function( const fn = () => {} ) | ⭕️ | ⭕️ |
メソッドの短縮記法( const obj = { method(){} ) | ❌ | ⭕️ |