ツイート
シェア
LINEで送る
B! はてぶでブックマーク
Pocketでブックマーク
RSSフィード

JavaScript ES2015, アロー関数ってなんだ?

JavaScript image
イラストダウンロードサイト【イラストAC】
の画像をもとに加工しています。

JavaScriptで関数っぽいんだけど、見たことないものをここ数年見かけます。

『どうせシンタックスシュガーでしょ?』と、まぁなんとなく分かっていたのでほっといたのですが、それはいかんだろうということできちんと調べました。

まず答えを言うと、シンタックスシュガーではありません。ES2015(ES6)から導入された新しい記法でした。

シンタックスシュガー(syntax sugar, 糖衣構文)

プログラムで、読みやすさ、書きやすさのために導入された書き方。

ドキュメントや書籍などの書式で多く出てくるものではなく、たまに出てくるので『通好み』『デキる人の書き方』に見られることが多い。

ECMAScript(エクマスクリプト)

JavaScriptの仕様のこと。Ecma International(エクマ・インターナショナル)がJavaScriptの書き方を決めている(仕様の策定・勧告)。

実質的な策定作業はTC39が行い、それに基づいてEcma Internationalが勧告する。勧告されると『ES20**(年代)』という名称がつけられる。

Ecma Internationalは、もともとヨーロッパの電子通信に関する標準化団体なので、JavaScriptだけを扱っているわけではない。

ES2015(ES6)

2015年に策定された第6版のこと。JavaScriptの従来の書き方から大幅に改善されたので、インターネット上の情報も多い。

ES2015から1年ごとに仕様を勧告することになったので、公式の名称では版数を使うのをやめた。(ES6は昔の言い方の名残り。正式なドキュメントには書いてある。)

ES6という呼び方は、変化の過渡期なので許されているだけ。

ES2016

2016年に勧告された仕様。ES7という表現が見られるが、ES2016のほうが分かりやすいのでES6ほど一般的じゃない。

ES5

2015年に大幅な変更が行われる前のJavaScriptの仕様。第5版。2009年に勧告。現在、どんなに古いバージョンのブラウザでも動かすことができる基準になっている。

JavaScriptのトランスパイルが簡単にできるようになったので、すべてのブラウザに対応できるJavaScriptの呼び方として使われる。

(トランスパイルは別のバージョンのJavaScriptのプログラムに変換すること。)

ESNext

次世代のJavaScriptの仕様のこと。まだ勧告されていなくてTC39で策定中の仕様のことを指す。

すべてのブラウザが対応していないES2015以降を指して使っていることも多い。

トランスパイルが簡単になったので、Reactなどのフレームワークや、Node.jsのプラグイン開発など、ESNextでプログラミングすることが当たり前になっている。

次世代の仕様なので、短くかんたんに書けることも多く、SPA(Single Page Application)などの大規模・複雑な開発で使われる。

もちろん、Nextの範囲はES20**がリリースされるごとに変わる。その状況は下記リンクにある。


各ブラウザとそのバージョンの、仕様の対応状況を確認することができる。

TC39(Technical Committee 39, 専門委員会39)

ECMAScriptの仕様の策定を行う専門委員会。Ecma InternationalはいろいろなTCを持っているので番号が振られている(ECMAScriptの仕様は39)。

作業中の内容や仕様などはGitHubで公開されていて確認できる。

作業は5ステージに分けて行い、すべてのステージが終了するとEcma Internationalが勧告する。

Stage 0Strawman
たたき台・試案
どんな仕様を導入するか? 策定作業に
入るか? を決める。
Stage 1Proposal
提案
仕様の策定作業の枠組みを作ったり問
題点の洗い出しを行う。
Stage 2Draft
下書き・草案
JavaScriptでじっさいに書く。
プログラミングの書き方を決める。

ドキュメントには『正確に』とあるの
で、あいまいなことは残さない。
Stage 3Candidate
候補
一般の開発者にドラフトを公開してフ
ィードバックする。
(お試し期間)
Stage 4Finished
完了
ECMAScriptの標準に追加できる準備
ができている状態。

いつでも勧告できることを表す。

各ブラウザは、勧告されるのを待っているわけではなく、独自に先行して導入することもある。その経過は誰でも確認できる

参考:TC39の公式ドキュメント

GitHub - tc39/ecma262

まずは、よく見かけるJavaScriptの関数の書き方から。

名前付き関数
function plus(a, b) {
    return a + b;
}
console.log(plus(1, 4));

これはかんたんですね? ほかのプログラム言語でも見る書き方です。コンソールログにplus()の結果『5』が表示されます。

無名関数
var plus = function(a, b) {
    return a + b;
}
console.lgo(plus(a, b));

もう一つ、無名関数と呼ばれるものです。JavaScriptやPHPなどWeb系のプログラム言語ではよく見る使い方。

関数を変数に格納できるオブジェクトとして扱い、その変数から関数をコールするやり方です。オブジェクトなので、そのまま関数の引数に指定することもできます。

無名関数では、よく『ラムダ式』『関数型プログラム』の言葉が出てきますが、調べるとまずいです。迷走します。ここではスキップしてください。

これらの言葉が分からなくても『百聞は一見に如かず』で、内容を見れば分かります。

ラムダ式、関数型プログラムは説明によって内容がまちまちです。でも間違いじゃないところが困りもの。

もともとの意味をたどるとまったく意味不明のところにたどり着くのでもっと困ります。

また、『関数リテラル』という言葉も出てきますが、深く考えすぎず『関数リテラル = 無名関数』と覚えたほうがいいです。

リテラル(literal)

ありのまま。文字どおりという意味から、プログラムに直接書くという意味。

JavaScriptの例
let num = 1;
let str = "string";
let arr = ['arr1', 'arr2', 'arr3'];
let obj = {ojb1:"xxx", obj2:"yyy"};

これらの右辺はすべてリテラル。配列の場合は配列リテラル、オブジェクトの場合はオブジェクトリテラルという。

リテラルと定数は異なるということに注意が必要。

定数値が変更できない変数のこと。
式の左辺。
リテラル定数に入れる固定値。
式の右辺。

無名関数(匿名関数)のことを関数リテラルという。無名関数は関数の引数に直接書くことがあるので『直接書いた関数 = リテラルな関数』と呼ばれる。

しかし、関数リテラルの意味をきちんと考えると迷走することがあるので、たんに『無名関数 = 関数リテラル』と覚えたほうが良い。

(じゃあ普通の名前付き関数は、直接書かれたもの(リテラル)じゃないのか? と思ってしまう。)

アロー関数は無名関数の新しい記法

やっと本題です。ES2015では無名関数に新しい書き方が加わりました。

アロー関数
let plus = (a,b) => { return a + b };
アロー関数のシンタックスシュガー
let plus = (a,b) => a + b;

まず上のコードの説明から。矢印(アロー, arrow)の左の()が関数の引数で、矢印の右の{}内が関数の処理の内容です。

そして、アロー関数がシンタックスシュガーでない理由がここから。この関数には省略形が存在します。シンタックスシュガーがあるということですね?

それが下のコードの書き方です。

  • 処理が1文なら、{}はなくてもいい。
  • 処理が1文でreturn構文だけなら、returnはなくてもいい。
  • 引数が1つなら、()はなくてもいい。

1文がreturnじゃない場合どうなるかというと、returnで返されちゃいます。でもその処理自体、戻り値を期待していないので無視すればいいだけ。

(返すものがない場合、undefinedを返す。)

引数が1つの場合は()が省略できます。例がなかったので、こんな感じです。

引数が1つのアロー関数
let plus = a => a * 2;

aを2倍にした値がplusに入ります。

引数がない場合、()は省略できません。

引数無しのアロー関数
let plus = () => 1 + 5;

plusに『6』が入ります。

オブジェクトを戻り値にする場合、注意が必要です。

オブジェクトを返すアロー関数
let plus = () => {test1:"xxxxx", test2:"yyyyy"};

これはエラーになります(Uncaught SyntaxError: Unexpected token)。

{}がオブジェクトのものではなく関数の{}だと勘違いするから。この場合は()でくくります。

オブジェクトを返すアロー関数
let plus = () => ({test1:"xxxxx", test2:"yyyyy"});

いろいろありますが、『こんなに略したら分からなくなるでしょ!』っていうくらいすっきりしています。

慣れるまでしばらく???が続きそうです。

このほか、thisの扱いが変わるなどあるのですが、それは別の機会に。とりあえずここまで。

前の投稿
JavaScript ES2015 var, let, const 変数宣言の使い方
Node.js npm, パッケージ管理の使い方。今やWebで必須のコマンド。
次の投稿

JavaScriptの本

post-cta-image

『自分は向いていない』『やってみたけど挫折した』『プログラマだけどjavaScriptは未経験』『フロントエンドエンジニアを目指したい』など、いろいろなタイプに合わせた書籍を集めました。

どうしてもネットで自分で調べるのが苦手という人におすすめです。

将来的には、書籍を買わずにネット上の公式ドキュメントで情報収集できるようなものを選んでいます。

コメントを残す

*