JavaScriptに関するお知らせ

SINCE2019
>
【JS】JavaScriptのバッククォートとカリー化の相性良すぎ問題

【JS】JavaScriptのバッククォートとカリー化の相性良すぎ問題


こんにちは!今日はJavaScriptのデザインパターンの一つ、バッククォート+カリー化について紹介します。

関数がめっちゃ綺麗になるぞ...!

結論

こういう書き方ができます

const greet = type => person => name =>
  `${type[0]}! ${person[0]} name is ${name[0]}.`

~greet`Hello``My``Mike`
// Hello! My name is Mike.

バッククォートの関数呼び出し

すごい簡単に言うと、関数を**こんなかんじ()じゃなくてこんなかんじ``**に呼び出せるってことです↓

const hello1 = name => `I'm ${name} .`
const hello2 = name => `I'm ${name[0]} .`

hello1('Mike') // I'm Mike.
hello2`Mike` // I'm Mike.

こちらの記事で色々書いてるわ。

カリー化

カリー化はあれだ、詳しくはwikipedia見てもらうとして

要はn個の引数をとる関数を1個の引数をとるn個の関数にバラす感じ。こんな風に。

const sum1 = (n, m) => n + m
const sum2 = n => m => n + m

sum1(10, 32) // 42
sum2(10)(32) // 42

バッククォートとカリー化を合体させてみよう

3つの引数をとる関数【greet】を想定します。それぞれ、【挨拶】【人称】【名前】をとって、【こんにちは】!【僕】の名前は【マイク】です! みたいな文章を作ります。

普通に書く

普通に書くとこう。

const greet = (type, person, name) => `${type}! ${person} name is ${name}.`

~greet('Hello', 'My', 'Mike')
// Hello! My name is Mike.

まあ全然読める。綺麗。ちなみにチルダ(~)はおまじないみたいなもんです。戻り値使わない関数には付けておこう。!や;でもいいよ。

バッククォートにしてみる...?

バッククォートにしてみたいけどバッククォートの関数呼び出しは引数1つしかとれんので一旦保留。

カリー化してみる

カリー化なら簡単。こう。

const greet = type => person => name => `${type}! ${person} name is ${name}.`

~greet('Hello')('My')('Mike')
// Hello! My name is Mike.

うーん綺麗になったかは微妙なところ?関数側は綺麗になったけど、呼び出し側は冗長に見えます。

バッククォート+カリー化

本題。どうぞ

const greet = type => person => name =>
  `${type[0]}! ${person[0]} name is ${name[0]}.`

~greet`Hello``My``Mike`
// Hello! My name is Mike.

えっやばい...呼び出し側がめっちゃ綺麗。関数側汚くなってるけどな

まだ驚くことなかれ、これちょっと適当にインデントして、他の例も書いてみると...

const greet = type => person => name =>
  `${type[0]}! ${person[0]} name is ${name[0]}.`

~greet`Hello``My``Mike`
// Hello! My name is Mike.

~greet`Hi``Our``Team Mike`
// Hi! Our name is Team Mike.

もはやJSではない。いやこれが真のJSか。別言語。もう別言語。 さすがにここまでインデントするのはやりすぎだけど、新世界が見えた。

実用例

【.このclass】を【クリック】したら【このメッセージ出す】みたいな処理考える。

const greet = name => event => greet =>
  document
    .querySelectorAll(name[0])
    .forEach(e => e.addEventListener(event[0], _ => alert(greet[0])))

~greet`.greet-button``click``こんにちは!クリックしてくれてありがとう!`

~greet`.greet-area``onmouseover``こんにちは!ここは挨拶エリア`

~greet`.confirm``click``本当によろしいですか?`

呼び出し側がシンプルすぎる。関数側はカオス。

ライブラリとかに使えそう?

さいごに

バッククォート+カリー化、特に呼び出し側はめっちゃ綺麗になる。一方で関数はカオスになる。

ライブラリとか共通の関数みたいな、処理がブラックボックス化できるケースでやるとよさそう。

あと例のごとくIEは全く駄目だ

以上!



PREV
2019-09-23
【JS】includes()の使い方に注意、書く順番を間違えやすい原因について

NEXT
2019-10-06
【JS】JavaScriptのundefinedを短く書く(最短4文字)