【JS】世界一美しい即時関数の書き方
こんにちは!今日はJavaScriptのテクニックの一つ、即時関数(IIFE)のとてつもなく美しい書き方を紹介します。随分攻めたタイトルだな。
結論
これです。
;(_ => console.log('Hello, World!'))``
美しすぎる。即時関数のごちゃっとした概念を完全に払拭。もはや宇宙。宇宙。 前後の余分なパーツ7文字。
Appleのジョブズの前のCEOが「私のコードを額縁に入れて飾りたい」って言ってたけど今なら気持ち分かる。
細かい解説
1行目
(_=>
この部分はアロー関数です。アロー関数はES6で追加された関数のクールな書き方よ。詳しくはこちらの記事に色々書いてあるわ。
第一引数が _ になってるのは引数を使わないの意です。lodashじゃないよ。_ じゃなくて() でもいいのでこう書いてもok
(()=>
2行目
console.log('Hello, World!')
{}がないです。この部分は式が1つの時に{}を省略できるアロー関数の特徴を用いています。{}付きならこうしてもok
{
console.log('Hello, World!')
}
1行目の関数をアローじゃなくすれば、こんな風にもできるね!
(function(){
console.log('Hello, World!')
3行目
)``
関数をバッククォートで呼び出しています。あまり知られていないけど、JSでは引数が1つ以下、かつ空か文字列の関数はバッククォートで定義できます。 即時関数は引数が空(の場合が多い)ので、バッククォートで使えるの。ここを普通の関数にするとこんな感じ。
)()
まあこれは見慣れた風景ね。
実際に使うには
まず、ES6に準拠しているか確認しましょう。アロー関数とバッククォートが使えんからな。つまりIEは死亡だ。
それと実際に使う時は、先頭に「~」を付けます。「;」か「!」でもいいけど。こんなかんじ
~(_ => console.log('Hello, World!'))``
これは詳しく説明すると長くなるけど、直前の式の終わりが値だった場合、その値を関数とみなさないために付けるのものです。
例えばこれはOKだけど…
const foo = 42
~(_ => console.log('Hello, World!'))``
これはエラーになる。
const foo = 42(_ => console.log('Hello, World!'))``
後者は値の42が42()みたいに関数として解釈されてまうのよね。これを防ぐには!~;のどれか付ければOKよ。 セミコロン書く派の人は特に意識しなくてもOK!
あと、処理は2つ以上の時は普通に{}付ければOKです。こんな感じ
~(_ => {
console.log('Hello, World!')
console.log('Hello, World!')
console.log('Hello, World!')
})``
引数を使いたいならバッククォート解除してこんな感じ。
~(name => console.log(`Hello, ${name}!`))('Tom')
ただし上述の通り引数が文字列ならバッククォートでもできる! これ他のサイトにはあんま書いてないよー!!
~(([name]) => console.log(`Hello, ${name}!`))`Tom`
引数とるとこに([])がいるのがめんどい。
おわりに
即時関数って結構おまじない感覚で書いてなかった?こんな風に…
;(function () {
console.log('Hello, World!')
})()
でも即時関数の仕組みをしっかり理解できれば応用も利くしクールに書けるしいいことだらけ!
~(_ => console.log('Hello, World!'))``
みんなも即時関数、してみてくれよな!