Edited at

JavaScript で if式っぽく動くようなswitch式...というかswitch関数作ったよ。


前の記事で if式 じゃなくて、if関数は作ってしまったのだ。

こちらの記事です。

JavaScriptの三項演算子が読みにくいらしいので、if式ならぬ if関数を作りました。そしてもっと読みにくい感。 - Qiita

https://qiita.com/standard-software/items/794724427fcee1cbd00b


どうせif関数も作ったので、真似て switch関数を作ります。

名前は「switch_」です。

値を渡したら、それを評価して分岐するという機能。

こんな書き方ができるようになります。


var switchValue = 1;
console.log(
switch_(switchValue)([
[1, 'Val1'],
[2, 'Val2'],
[3, 'Val3'],
['1', 'ValStr1'],
['defaultVal']
])
);

var switchValue = '1';
console.log(
switch_(switchValue)([
[1, 'Val1'],
[2, 'Val2'],
[3, 'Val3'],
['1', 'ValStr1'],
'defaultVal'
])
);

特定条件によって値を代入するときに let 変数じゃなくて const 変数を使いたい場合でも、この「switch_関数」を使えば使い放題です。(使わなくても工夫したら使いたい放題だろうけれどもな)

上の書き方、細かくみてみるとわかるように、配列じゃない値を渡したり、長さ1の配列を渡すとそこがデフォルト値になります。

数値の1と、文字列の1の比較もできるぞ、という感じ。

なぜ配列にしているかというと、オブジェクトだと、{1: 'Val1', '1': 'ValStr1'} こんな書き方ができないから。オブジェクトのプロパティは全部文字列に変換されるらしいよ。


「switch_」関数の実装

ということで実装です。結構簡単。

const isFunction = (value) => {

return (typeof value === 'function');
};

const functionValue = (value) => {
if (isFunction(value)) {
return value();
} else {
return value;
}
};

const assert = function (value, message) {
if (typeof message === 'undefined' || message === null) {
message = '';
}
if (value !== true) {
throw new Error(message);
}
};

const switch_ = (expression) => {
return (args) => {
assert(Array.isArray(args), 'switch_ function');
for (let i = 0; i < args.length; i += 1) {
if (!Array.isArray(args[i])) {
return args[i];
} else if (args[i].length === 0) {
return undefined;
} else if (args[i].length === 1) {
return args[i][0];
} else {
if (args[i][0] === expression) {
return functionValue(args[i][1]);
}
}
}
};
};

if_関数の実装と同じように、内部で、functionValue を使っているので、次のように書けば、条件合致しない部分のものは、関数呼び出しそのものが行われません。

これで場合によっては、値によって関数呼び出しを制御する、ということも簡単にできます。

var switchValue = 2;

console.log(
switch_(switchValue)([
[1, _=>'Val1'],
[2, _=>'Val2'],
[3, _=>'Val3'],
['1', _=>'ValStr1'],
'defaultVal'
])
);

switch_関数は、if_関数よりかはいくらか実用的かもしれないですね。

まあ、これもお遊びみたいなものですが、こんなこともできる。ってことで。よろ。


追記

2019/03/21(木)

switch_ を組み込んだライブラリを npm で配信しています。TypeScriptコードです。

standard-software/copipejs: simple code parts

https://github.com/standard-software/copipejs

デフォルト値の記載方法を少し変えました。

https://github.com/standard-software/copipejs/blob/master/build/tsc/node/copipe_core.js

このあたりのソースをみると実装がわかり、

https://github.com/standard-software/copipejs/blob/master/source/test/node/test_copipe_core.js

こちらのテストコードをみると使い方がわかります。