クモのようにコツコツと

フロントエンドエンジニア イイダリョウのブログ。略称「クモコツ」

【JS】アロー関数の複数の書き方を試してみた

ES6(ES2015)で追加されたアロー関数。従来の関数よりもコンパクトに書けます。IE非対応とはいえ、もう5年も経っているのでそろそろこちらをメインで行きたい!アロー関数には複数の書き方があります。自分的に直感的ではないと感じた書き方もありましたが、人が書いたコードを読むためにも実際に試してみる。あと、イベントリスナと引数の関係についても勉強になった。それでは行きましょう!

【目次】

※参考:従来の関数(function)の書き方
【JSの基本-前編】書ける前に読む!HTML、CSS、JSの書式-4 - クモのようにコツコツと

※参考:ネイティブJSやってみたシリーズ
qiita.com

アロー関数のブラウザ対応状況(IE以外AllOK!)

アロー関数とはざっくりいうとJSの関数をfunctionの代わりにアロー(矢印)=>が使えるよー、という書き方。ES6(2015)から採用されてもう5年経つ。

caniuseで見るとIE以外のブラウザは対応済み!

f:id:idr_zz:20200208181926j:plain

※参考:Can I use... Support tables for HTML5, CSS3, etc

IE11のシェアは全体では10%切っているがデスクトップだけで見るとまだ12%ある。。(2020/02/08現在)

Source: StatCounter Global Stats - Browser Market Share

しか〜し、IE11がデフォルトブラウザのWindows7がめでたく今年の1/14に終了!

※参考:https://support.microsoft.com/ja-jp/help/4057281/windows-7-support-ended-on-january-14-2020

以前、長く愛好されたWindows XPがサポート終了するとデフォルトブラウザのIE8も急速にシェアが減って行ったので、これからIE11のシェアはどんどん下がっていくと予想(熱望)している!

また、何度でも紹介するがw 今やマイクロソフト自体も「IEを使わないて」と明言しています。

※参考:「Internet Explorer使わないで」開発元のマイクロソフトが警告 | ハフポスト

進化を止めたブラウザでありながら、ユーザーが使い続けているがためにサポートし続けなければならないIE。。我々が使うのをやめればマイクロソフトもEdgeやらVSCodeやらAzureやらの進化にリソースを避けるわけです。

時はきた!」令和時代はどんどんEcmaっていこうぜい!!

アロー関数でクリックイベント

では、アロー関数とはどんな書き方か。最近ではよく見るので自分もなんとなくはわかっているが自分でも正確に書けるようちゃんと調べる。

アロー関数の書き方は複数あったので、実際に書いてみた。ちゃんと動く。

See the Pen arrow func by イイダリョウ (@i_ryo) on CodePen.

ボタンを押すとアラートが立ち上がるクリックイベントを設定。この中にアロー関数の書き方をいくつか試した。

ボタンにそれぞれclass名を付けてある。

HTMLコード

<div class="btns">
    <p>アロー関数のいろんな書き方</p>
    <button class="yesname">普通の関数</button>
    <button class="noname">無名関数</button>
    <button class="arrow1">アロー関数1</button>
    <button class="arrow2">アロー関数2</button>
    <button class="arrow3">アロー関数3</button>
</div>

一つ目の「普通の関数」のclass名.yesnameは実際にはそんな言い方しないけどその下の無名関数に対応した名前にしたw

JSのquerySelector()でボタンのclass名を取得。

JSコード

//DOM取得
const yesname = document.querySelector('.yesname');
const noname = document.querySelector('.noname');
const arrow1 = document.querySelector('.arrow1');
const arrow2 = document.querySelector('.arrow2');
const arrow3 = document.querySelector('.arrow3');

さあ準備は整った。

従来の関数(function宣言)

まずは従来の関数の書き方。

//従来の関数
function yesnameFunc() {
    alert( yesname.innerHTML );
}

functionで関数宣言*1して、その中に処理を定義する。これまで使い慣れてきた書き方。

関数の中の処理はアラートで、innerHTMLで取得したDOMの中のテキストを表示する。

関数は定義するだけでは実行されない。実行したい場所から関数を読み込む。

//関数を実行
オブジェクト.yesnameFunc();

このように関数名に引数のカッコを付けて書く。

※参考:【JSの基本-前編】書ける前に読む!HTML、CSS、JSの書式-4 - クモのようにコツコツと

//イベントリスナ
yesname.addEventListener( 'click', yesnameFunc, false );

ただし、イベントリスナから読み込んで実行する場合は引数のカッコを付けない!

※参考:【JSの基本-後編】書ける前に読む!HTML、CSS、JSの書式-5 - クモのようにコツコツと

今回はイベントリスナを使ったクリックイベントなのでこの形になる。

無名関数

次に無名関数。先ほどの関数宣言とは書き方は違うが挙動は同じ。

//無名関数
const nonameFunc = function() {
    alert( noname.innerHTML );
}

変数nonameFuncの中に「無名関数」functon ()の処理を代入する。無名関数=関数名がない!

関数の実行は関数宣言と同じ書き方でOK。

//関数を実行
オブジェクト. nonameFunc();

変数名=関数名になる。

無名関数はその場限りで(再利用しない)で行われる処理に多用する。イベントリスナの中でもよくこんな風に書く。

//イベントリスナの中の無名関数
noname.addEventListener( 'click', function () {
    alert( noname.innerHTML );
}, false );

今回は他と揃えて外部から関数を呼び出す形で実行する。

//イベントリスナ
noname.addEventListener( 'click', nonameFunc, false );

こちらも引数のカッコを付けない。

ここまでが冒頭の2つのボタン「普通の関数」「無名関数」の部分。

アロー関数の基本形

さあいよいよここからアロー関数を書いてみる!

※参考:アロー関数 - JavaScript | MDN

最初に「functionの代わりにアロー(矢印)=>が使えるよー」と書いた。7文字が2文字に!コンパクト!

こちらは「アロー関数1」ボタンのJSコード

//アロー関数1(Functionをアローに)
const arrow1Func = () => {
    alert( arrow1.innerHTML );
 }

アロー関数は2番目の「無名関数」と同じく変数の値として設定する。

ただこの二つはただそのまま書き換えれば良いわけではない。function ()() =>、つまり引数のカッコと順番が入れ替わる。

関数の実行は変わらない(以降のアロー関数も同じ)

//関数を実行
オブジェクト. arrow1Func();

今回はイベントリスナなのでカッコなし。

//イベントリスナ
arrow1.addEventListener( 'click', arrow1Func, false );

アロー関数には他にも書き方があるので書いてみる。

処理が1行だとブロックを省略できる

次、「アロー関数2」のJSコード。

//アロー関数2(処理が1行:ブロックを省略)
const arrow2Func = () => alert( arrow2.innerHTML );

関数の中の処理が1行のみの場合はブロックの波カッコ{ }を省略できるようだ。さらにコンパクトになった!

関数の実行。

//関数を実行
オブジェクト. arrow2Func();

今回はイベントリスナなのでカッコなし。

//イベントリスナ
arrow2.addEventListener( 'click', arrow2Func, false );

引数が1つの場合は引数カッコも省略できる

最後、「アロー関数3」のJSコード

//アロー関数3(引数が1つ:カッコも省略)
const arrow3Func = text => alert(text);

textarrow3Func関数の引数。alert()の中にtextを格納する。

なんと!引数が1つだけの時は引数を囲うカッコまで省略できるみたい!(引数が0個または複数個の場合はカッコを省略不可)

ただ、個人的にはこの書き方はコンパクトすぎて分かりにくくなっていると感じた。。(慣れの問題かな?)

テキストエディタでカッコを選択すると閉じカッコも印が付いて直感的なのでいいと思うんだけど…。

しかし、こういう書き方がある事を知っておくことは、自分が書くかどうかは別として、他の人のコードを読むためにも必要かなと。(よりコンパクトに書きたい人もいるはず)

ちなみに、引数がある関数については実行させるときの書き方が少し違ったので項を分ける。

引数ありの関数をイベントリスナで実行(無名関数でラップ!)

引数ありの関数の実行はこんな感じ。

//arrow3に表示したいテキスト
const arrow3Text = arrow3.innerHTML;

//関数を実行
オブジェクト.arrow3Func(arrow3Text);

arrow3Func()の引数の中にアラートで表示したい変数arrow3Textの値を代入する。

ただし、イベントリスナで関数を外部から読み込む場合はカッコを付けれない!(無名関数は引数ありでもOK)

※参考:【JSの基本-後編】書ける前に読む!HTML、CSS、JSの書式-5 - クモのようにコツコツと

ダメ元で引数を付けてで書いてみたが、やはり動かなかった。。

//arrow3に表示したいテキスト
const arrow3Text = arrow3.innerHTML;

//引数を付けると動かない。。
arrow3.addEventListener( 'click', arrow3Func(arrow3Text), false );

どうしたらいいか調べたところ、引数ありの関数を引数なしの無名関数でラップする方法があった!

※参考:addEventListenerで関数に引数を渡す - Qiita

引数なしの無名関数でラップしてみる。

//arrow3に表示したいテキスト
const arrow3Text = arrow3.innerHTML;

//引数付きは無名関数でラップする
arrow3.addEventListener( 'click', () => {arrow3Func(arrow3Text)}, false );

addEventListener()の第二引数の部分、arrow3Func(arrow3Text)の外側に無名関数をラップする。 これによってarrow3Func(arrow3Text)が引数付きでも「引数なし」と同じ状態になる。

無事に動かすことができた!この方法は初めて知った!勉強になった!

アロー関数の書き方まとめ

最後に従来の関数とアロー関数の定義部分だけをまとめる。

See the Pen arrow func by イイダリョウ (@i_ryo) on CodePen.

こちらのボタンに紐づけられています。

関数宣言

まずは従来の書き方。関数宣言。

//従来の関数
function yesnameFunc() {
    alert( yesname.innerHTML );
}

馴染み深い書き方。

無名関数

無名関数

//無名関数
const nonameFunc = function() {
    alert( noname.innerHTML );
}

変数に関数を代入。これも同じ動き。

アロー関数(基本)

ここからアロー関数。最初に基本形。

//アロー関数1(Functionをアローに)
const arrow1Func = () => {
    alert( arrow1.innerHTML );
 }

functionとアロー=>は順番が逆になる。

ブロック省略(処理が1行)

処理が1行の時はブロックが省略できる。

//アロー関数2(処理が1行:ブロックを省略)
const arrow2Func = () => alert( arrow2.innerHTML );

引数のカッコ省略(引数が1つ)

さらに引数が1つだと引数のカッコも省略できる。

//アロー関数3(引数が1つ:カッコも省略)
const arrow3Func = text => alert(text);

ここまでいくと分かりにくいかも。。=>を見落とさないよう注意!
(引数付きの関数をイベントリスナで読み込む時には引数無しの無名関数でラップすることも注意)

最後に

ということで大変コンパクトになったアロー関数でした。これまでよりもかなりコンパクトな書き方ができることがわかりました!ただ、個人的にはカッコ系を省略しすぎると直感的ではないように感じました。自分はカッコは付けて行こうかと思っています。(functionの7文字が=>の2文字になるだけでもだいぶ楽!)

コンパクトすぎる書き方も慣れれば快適に感じるのかもしれない。冒頭にも書いたようによりコンパクトな書き方をしたい人はこの書き方をしている可能性もあるので、少なくとも知識としては知っている必要がありますね!

あとアロー関数は単にコード記述量が短かくなるだけでなく、従来の関数とは挙動が異なる部分もあるみたい。特に影響が大きそうなのはthisです。これについてはちょっと長くなりそうだったので回を分けたく思います。それではまた!


※参考:ネイティブJSやってみたシリーズ
qiita.com

*1:関係ないけど一瞬「関白宣言」に見えるw