- JavaScriptの関数宣言には、
function キーワードを使った宣言、関数式、アロー関数などさまざまな方法がある
- 関数宣言には ホイスティング が適用されるため、コード内のどの位置からでも参照できる
- Arrow(アロー)関数は 簡潔な構文 が利点だが、this/arguments/super のバインディングがない など重要な違いがある
- コンストラクタ関数、ジェネレーター、メソッド にはアロー関数の使用は適していない
- 単純なコールバックや無名関数 には アロー関数 のほうが適している
Function Declarations, Function Expressions, and Arrow Functions
- JavaScriptでは、関数宣言(Statement)、関数式(Expression)、アロー関数(Arrow Function) の3つの方法で関数を定義できる
- 関数宣言は
function isVowel(chr) { ... } のように名前を直接バインドし、コードのどこからでも参照可能(ホイスティング)。スタックトレース や デバッグ の際にも関数名が明確に表示される
- 関数式は
const takeWhile = function(predicate, arr) { ... } のように、変数に無名関数を代入する形
- 関数式にも内部的に名前を付けられるが、その名前は外側のスコープにはバインドされず、主に スタックトレースでのエラー追跡に使われる
Hoisting and Naming
- 関数宣言文 はJavaScriptエンジンによって ホイスティング されるため、宣言前に呼び出しても動作する
- 無名の関数式は、変数への代入後にのみ呼び出し可能
- デバッグのために関数へ 明示的に名前を付ける ことは、スタックトレース上で有利になる場合がある
Arrow Functions
Practical Example: thisとコンストラクタ、ジェネレーター
- 通常の関数とアロー関数での this の扱いの違いを示す例を紹介
- オブジェクト内でメソッドとして使う場合、通常の関数では this はオブジェクト自身を指すが、アロー関数では undefined または外側のスコープの this を指す
- コンストラクタ関数をアロー関数で定義すると TypeError が発生する
- ジェネレーター関数は必ず
function* 構文を使う必要がある
どの関数構文をいつ選ぶべきか?
- ジェネレーター(yield を使用) が必要 →
function* を使う
- this を活用 する必要がある →
function キーワードまたはクラスメソッドを使う
- ホイスティング が必要、または上位レベルでの可読性を重視したい → 関数宣言文を使う
- 上記に当てはまらないなら → アロー関数 でより簡潔に書くのが有利
結論
- JavaScriptの関数は、用途、this の必要性、コンストラクタ/ジェネレーターかどうかによって構文を選ぶ
- 日常的なコールバック/単純な関数 には アロー関数 が最適
- オブジェクトメソッド/コンストラクタ/ジェネレーター には
function 構文が必要
- ホイスティング や宣言順序の自由度が必要なら、関数宣言文が有利
3件のコメント
根本的な点と同じくらい、
prototypeの有無も ...生成される高階関数のリファレンス方法も ...
const a = (a: () => null): (() => () => null) =>() => a
() => ❤️