JavaScript

【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!')
)``

みんなも即時関数、してみてくれよな!