hyper-functionはJavaScriptで(擬似的に?)名前付き引数とオーバーロード可能な関数を利用するためのライブラリです。
# NPM
npm install hyper-function
# yarn
yarn add hyper-functionhyper-functionはES6のimportで読み込むことができます。
import hyper from 'hyper-function'hyper-functionだと名前が長いのでhyperとしてインポートしています。
関数を定義するには
const func = hyper([
{
引数1: 型,
引数2: 型,
引数3: 型,
引数...: 型,
_({ 引数1, 引数2, 引数3, 引数... }) { /*処理*/ },
},
{
引数1: 型,
引数2: 型,
引数3: 型,
引数4: 型,
引数...: 型,
_({ 引数1, 引数2, 引数3, 引数4, 引数... }) { /*処理*/ },
},
])このように記述します。
型についてはJavaScriptのプリミティブ型のみ対応しています。
現在自作型(クラス)とAny型(なんでも対応できる型)を開発しています。
const Vec2 = hyper([
{
x: Number,
y: Number,
_({ x, y }) {
return { x, y }
}
},
{
xy: Number,
_({ xy }, call) {
return call(xy, xy)
}
},
{
_(call) {
return call(0)
}
}
])Vec2関数は3つのパターンがあります。
x, yを受け取り{x, y}を返すパターンxyを受け取り{x: xy, y: xy}を返すパターン- 何も受け取らずに
{x: 0, y: 0}を返すパターン
それぞれ
//x, yを受け取り{x, y}を返すパターン
Vec2(10, 20)
//=>{x: 10, y: 20}
//xyを受け取り{x: xy, y: xy}を返すパターン
Vec2(32)
//=>{x: 32, y: 32}
//何も受け取らずに{x: 0, y: 0}を返すパターン
Vec2()
//=>{x: 0, y: 0}このように使えます。
1つめのx, yを受け取り{x, y}を返すパターンの実装は
{
x: Number,
y: Number,
_({ x, y }) {
return { x, y }
}
},このようになっています。
最初の
x: Number,
y: Number,で引数を定義します。この場合だとNumber型のxとNumber型のyを定義しています。
次の
_({ x, y }) {
return { x, y }
}これはこのパターンの処理部分です。
必ずパターンの処理関数の名前は_にしてください。
引数の_({ x, y })は先程のNumber型のxとNumber型のyに対応しています。
なお
_({ x, y }) {
return { x, y }
}は
_(data) {
return { x: data.x, y: data.y }
}
と書き換えれます。2つめのxyを受け取り{x: xy, y: xy}を返すパターンの実装は
{
xy: Number,
_({ xy }, call) {
return call(xy, xy)
}
},このようになっています。
引数はNumber型のxyのみです。
処理部分は
_({ xy }, call) {
return call(xy, xy)
}このようになっています。
先程のパターンとは違い、第二引数にcallという引数があります。
そしてreturn call(xy, xy)を返しています。
これは先程のパターン(x, yを受け取り{x, y}を返すパターン)のを呼び出しています。
何も受け取らずに{x: 0, y: 0}を返すパターンの実装は
{
_(call) {
return call(0)
}
}引数が空の場合はいきなり第一引数でcallを受け取れます。
ちなみにこのcall(0)は先程の引数がxyだけのパターンを呼び出しています。
人の情報を返すHuman関数があるとします。
Human関数は名字と名前と生まれた月と日を受け取ります。
実装は以下のとおりです。
const Human = hyper([
{
FirstName: String,
LastName: String,
BirthdayMonth: Number,
BirthdayDay: Number,
_({ FirstName, LastName, BirthdayMonth, BirthdayDay }) {
return {
FirstName,
LastName,
BirthdayMonth,
BirthdayDay
}
}
}
])使用例:
Human('Taro', 'Yamada', 4, 6)この例だけ見ると名前がYamada Taroということは分かるのですが、次の4, 6が4月6日なのか6月4日なのか�はっきりしません。
そんなときに*名前付き引数(NamedParameter)*が役立ちます。
NamedParameterを使うにはhyper-functionをimportする部分を以下のようにします。
import hyper, { NamedParameter as Np } from 'hyper-function'先程の例を名前付き引数で呼び出してみます。
Human(Np.Firstname = 'Taro', Np.Lastname = 'Yamada', Np.BirthdayMonth = 4, Np.BirthdayDay = 6)
//=> {FirstName: "Taro", LastName: "Yamada", BirthdayMonth: 4, BirthdayDay: 6}このように
Np.引数名 = 値で引数を渡しています。
といっても最初のTaroとYamadaはどんな意味なのかは分かるので生まれた月と日だけ名前付き引数で渡すと
Human('Taro', 'Yamada', Np.BirthdayMonth = 4, Np.BirthdayDay = 6)
//=> {FirstName: "Taro", LastName: "Yamada", BirthdayMonth: 4, BirthdayDay: 6}こんなかんじです。 だいぶ見やすいと思いませんか?
ちなみに名前付き引数は順番を変えても正常に動作します。
// BirthdayMonthとBirthdayDayの一を入れ替えた
Human('Taro', 'Yamada', Np.BirthdayDay = 6, Np.BirthdayMonth = 4)
//=> {FirstName: "Taro", LastName: "Yamada", BirthdayMonth: 4, BirthdayDay: 6}引数にはデフォルト値を付けれます。
通常引数を定義するときは
引数名:型ですが 引数のデフォルト値を付けるには
引数名: {
type: 型,
default: () => デフォルト値
}のように記述します。