【TypeScript / JavaScript】this = “これ” ← どれ? 【備忘録】

111 ※Web開発
【TypeScript / JavaScript】this = "これ" ← どれ? 【備忘録】 - Qiita
この記事で分かることTypeScript(JavaScript)における関数の宣言方法各宣言方法におけるthisの扱い初めに初めまして。新人エンジニアをしているものです。先日TypeScr…
  • TypeScript(JavaScript)における関数の宣言方法
  • 各宣言方法におけるthisの扱い

(前提)TypeScriptの関数の宣言方法

まずは複数ある関数の宣言方法を簡単にまとめます。

①function構文による宣言

function sum (a : number, b : number) : number {
    return a + b ;
}
  • JavaScriptでよくみられる記法
  • TypeScriptでは引数と戻り値に型注釈を付けられる
    • 変数の型注釈を書かない → any型判定
    • 戻り値の型注釈を書かない → 型推論
  • 巻き上げ(宣言した行の前の行で呼び出すこと)が可能

②function式による宣言

const sum = function funcName (a : number, b : number) : number {
    return a + b ;
}
  • 関数宣言は文であるのに対し、関数式は式
    → 変数に直接代入可能
  • 関数名は省略可
  • function式で宣言された関数名は関数内でのみ利用可能
  • 巻き上げ不可

③アロー関数による宣言

const sum = (a : number, b : number) : number => {
    return a + b ;
}
  • ほかの二つと比べて比較的新しく実装された機能
  • 関数式同様、アロー関数は式
  • 短く書くことができる
  • 引数が一つだけ、処理が一行だけの時は省略形で書ける※型注釈は書けない

thisのふるまいの違い

アロー関数以外におけるthis

-> 実行時にthisのふるまいが決まる
関数におけるthisの基本的な参照先はベースオブジェクト(メソッドを呼ぶ際に.の前に置かれているオブジェクトのこと)を指します。
下の例では、this.nameを出力する関数funcを二通りの方法で呼び出しています。

function func () {
    console.log(this.name)
}

const obj {
    name : "Baki",
    func : func(),
    }
}

// 1.単純に関数として呼び出す
func();  // "undefined"

// 2.obj のメソッドとして呼び出す
obj.func();   // "Baki"

1の方法で呼び出す場合には、ベースオブジェクトが存在していない場合、undefinedが出力されます。
対して、2の方法で呼び出す場合にはobjがベースオブジェクトとなるため、objに含まれるnameプロパティの値が出力されます。

※お使いの環境がstrict modeを利用している(コードに"use strict"と明記されている)場合、”undefined”ではない結果が出力されているかもしれません。これはthisがundefinedの場合はグローバルオブジェクトをベースオブジェクトとするというJavaScriptの仕様によるものです。

このように、呼び出し方でふるまいが変わるのがアロー関数以外におけるthisです。

アロー関数におけるthis

->宣言時に決まる静的な値
アロー関数はにおけるthisはレキシカルなスコープを持っています。端的に言えば静的な値のことで、宣言時の値を格納し、ベースオブジェクトには左右されません。
下の例では上と同様、this.nameを出力する関数funcを二通りの方法で呼び出しています。

const func = () => {
    console.log(this.name)
};

const obj = {
    name:"Yujiro",
    func:func
}

// 1.単純に関数として呼び出す
func();    // "{}"

// 2.objのメソッドとして呼び出す
obj.func();    //{}

実際に適当な環境で実行していただければわかるかと思いますが、いずれの呼び出し方法でも空のオブジェクト{}が出力されていることがわかるかと思います。
上述の通り、アロー関数は宣言時のthisを参照するため、1行目で使っているthis(未定義なので空のオブジェクト)が出力されています。

まとめ

今回は関数の宣言方法とそれらの差、アロー関数とそれ以外の宣言方法におけるthisの違いについてまとめました。
一見、thisが動的に変化するfunction構文・式による宣言方法は便利に思えますが、strict modeを使用していないと予想外の値を参照してしまい、想定とは異なる挙動につながりかねません。
同じような用途でも細かい仕様が異なる機能はほかにもあるので、逐次調べつつ、日々精進したいと思います。

参考サイト

タイトルとURLをコピーしました