技術メモなど

業務や日々のプログラミングのなかで気になったことをメモしています。PHP 成分多め。

JavaScriptのアロー関数について調べた

数年振りにJavaScriptを触ることになりそうなので、改めて今時の仕様をきちんと理解したいと思いいろいろ調べている。 今回はアロー関数について調べたのでメモ。

アロー関数とは

アロー関数式は、より短く記述できる、通常の function 式の代替構文です。また、this, arguments, super, new.target を束縛しません。アロー関数式は、メソッドでない関数に最適で、コンストラクタとして使うことはできません。
アロー関数 - MDN

// 通常のfunction式による関数定義
var hoge = function(){
    console.log('hoge');
};

// アロー関数式を使った定義
var hoge = () => {
    console.log('hoge');
};

短縮構文

アロー関数では、引数の()やブロックの{}を省略できる場合がある。

// 引数がひとつの場合、()を省略できる。
var hoge = arg => { return arg }; 
console.log(hoge(1)); // 1

// 引数が複数の場合、()は省略できない。
var hoge = arg1, arg2 => { return arg1 + arg2 }; 
console.log(hoge(1)); // SyntaxError: Unexpected token =>

// 本体が単一の式の場合、{}およびreturnを省略できる()。
var hoge = arg =>  arg + 1; 
console.log(hoge(1)); // 2

// 戻り値がオブジェクトリテラルの場合、()を付与する必要がある。
var hoge = arg => ({foo: arg}); 
console.log(hoge(1)); // { foo: 1}

// 本体が複数の式の場合、{}は省略できない。
var hoge = arg =>  arg + 1; arg + 2;
console.log(hoge(1)); // ReferenceError: arg is not defined

this

通常の関数は、関数ごとに自身のthisを定義するが、 アロー関数式のthisは、自身のthisを持たず、レキシカルスコープのthisを使用する。 つまり変数探索ルールと同じような挙動をする(現在のスコープ内にthisがない場合、外側のスコープを探索し、最終的にグローバルスコープに到る)。

// function式
const tarou = {
    family_name: '山田',
    first_name: '太郎',
    fullname: function(){
        console.log(`${this.family_name} ${this.first_name}`);  
    }
};
tarou.fullname(); //山田 太郎

// アロー関数式
const hanako = {
    family_name: '山田',
    first_name: '花子',
    fullname: () =>{
        console.log(`${this.family_name} ${this.first_name}`);  
    }
};
// hanako.fullname()内のthisは外側のthis(=グローバルオブジェクト)を
// 参照しているため、undefinedが返る。
console.log(hanako.fullname()); //undefined undefined

コールバック関数を利用する場合、従来のfunction式ではthisがグローバルオブジェクトを参照するため、呼び出し元のthisを参照したい場合var self = thisのように変数に一時代入しなければならなかったが、アロー関数式は実行時のスコープ内のthisを参照するためその必要がなくなった。

const hoge = {
    count: 0,
    // コールバック関数に通常の関数を渡す
    func: function(){
        setTimeout(function(){
            // このthisはグローバルオブジェクトを参照している
            this.count++;
            console.log(this.count);
        }, 1000)  
    },
    // コールバック関数にアロー関数を渡す
    arrowfunc: function(){
        setTimeout(()=>{
            // このthisは外側のthis(=hoge)を参照している
            this.count++;
            console.log(this.count);
        }, 1000)   
    }
};
hoge.func(); // NaN
hoge.arrowfunc(); // 1

参考文献

アロー関数 - MDN