WebEngine

だらだらと綴る技術系メモ

元弓道部、アロー関数を勉強する

f:id:web-engine:20190609234801p:plain

アロー関数に救われたい

高校時代、弓道部に所属していました。
高校に入って、部活の見学をしていたとき、先輩たちの放った矢がズドンと音を立てているのを聞いて、入部を決めました。
授業は嫌いでしたが、部活は結構楽しかったので、学校にはちゃんと行っていたのかもしれません。


時は流れ、筆者はプログラマになり、JavaScriptアロー関数と出会います。

アロー(arrow)とは、矢、もしくは矢印のこと。
) =>の部分は、弓矢に見えないこともありません。
弓道部として、親しみを覚えました。

願わくば、弓道と同じく、アロー関数が過酷なエンジニア生活に恵みをもたらしてくれることを期待します。

アロー関数の特徴

アロー関数は、大きく2つの特徴を持ちます。

  1. 短く記述できる
  2. thisの値の固定

これらを順に見ていきます。

(注意点としてIEの未対応が挙げられます)

特徴1.短く記述できる

ES6以前の書き方はこんな感じでした。
(ES6とは、2015年に標準として策定されたJSの新しい文法を指す)

const test = function(x){
    return x + x;
}


アロー関数だと、functionを省略できます。

const test = (x) => {
    return x + x;
}


さらに、関数の中身が一文だけならば、中括弧を書かなくてもOK。
returnも記述不要になります。

const test = (x) => x + x;

なんか疾走感あって好き。

2019.6.14 追記

場合によっては()すら省略できます。

// 引数が1つならば()は省略可
const test = x => x + x;
// 引数が2つ以上の場合は省略不可
const test = x, y => x + y;  // Uncaught SyntaxError: Missing initializer in const declaration
const test = (x, y) => x + y;  // OK
// 引数がない場合、省略不可
const test = () => "test";


特徴2.thisの値の固定

MDNは、この「固定」という言葉を「束縛」と表現しています。
(この「束縛」という表現ですが、MDNでは、時期によって定義が変わっていたみたいで、「束縛する」「束縛しない」の混在が見られます)


筆者が参考したなかで、わかりやすかった表現は

アロー関数式で宣言された関数は、宣言された時点で、thisを確定(=束縛)させてしまう

というものです。
引用元: 【JavaScript】アロー関数式を学ぶついでにthisも復習する話


一般的にJSでは、関数内でthisを使うと、その呼び出し元のオブジェクトとして扱われます。

// letやconstを付加していないのでグローバルとして定義されている
param = 'test';

function normalFunc() {
  console.log(this.param);
}

const hoge = {
  param: 'hoge',
  func: normalFunc
}

hoge.func();  // hoge

上記ソースコードでは、グローバルのtestではなく、オブジェクト内部で定義されているhogeが出力されました。
thisの値は、関数がコールされるときに決定され、関数を定義した段階ではthisはなにを指すか決まっていないということです。


ですが、アロー関数で定義したときに挙動は上とは違います。

// letやconstを付加していないのでグローバルとして定義されている
param = 'test';

const arrowFunc = () => console.log(this.param);

const obj = {
  param: 'hoge',
  func: arrowFunc
}

obj.func();  // test

呼び出し元のオブジェクトが存在しない状況においては、thisは、グローバルオブジェクトを指します。

param = 'test';
console.log(this.param);  // test

この状態でアロー関数を定義すると、アロー関数式で宣言された関数は、宣言された時点で、thisを固定するので、testが出力されるという理屈です。


で、アロー関数でthisが固定化されているとどんなメリットがあるのかというと

var self = this;

みたいな記述しなくて済んだりします。


裏を返せば、既存のプログラムを修正する場合などは、thisによってプログラムの挙動が違ってきますので、アロー関数に置き換える際には注意が必要になります。

まとめ

アロー関数を使えば、短く書くことができる。
ただし、thisの挙動における最低限の知識を持っていないと、その鋭利な矢先を自らに向けることなる。


参考