チェインされないコードを無理矢理チェインさせる方法
最近ラムダ式やチェインの為に自身を返すコードが流行となっている。
その中で自身を返さない文があると、チェインや三項演算子が使えない。
その場合に無理矢理自身を返すようにする方法
先に完成形
const name = 'hello taro';
const address = 'tokyo';
const age = [ 1900, 2000 ];
console.log(
{ 'name' : name, 'address' : address, ...age
.reduce((a, c) => !a ? { startAge : c } : (() => { a['endAge'] = c; return a; }).call(), null)
}
);
このコードで問題なのが、
a['endAge'] = c; return a;
の部分
aを返したいのだが、a['endAge'] = cの部分でaを返してくれないのでchainできない。
その為aを返すように明示的に指定しないといけない。
しかし2文にすると、{}で囲まないと行けなくなる。
しかし一部を{}で囲むと、全部を{}で囲みreturn文が必要になる。
.reduce((a, c) => {
if (!a) {
return { startAge : c };
} else {
a['endAge'] = c;
return a;
}
});
処理内容自体は単純なので、すべて{}とreturnを付けると、なんかイヤだ。
すると、次に考えるのは
「匿名関数で囲めば出来るのではないか」
.reduce((a, c) => !a ? { startAge : c } : function() { a['endAge'] = c; return a; }, null);
「匿名関数ではfunction文字が邪魔なのでラムダ式にする」
この考え方で、コードを組むとこのようになる。
.reduce((a, c) => !a ? { startAge : c } : () => { a['endAge'] = c; return a; }, null);
ここまで短くなると「return」文字でさえ邪魔だが、これはどうしようもない。(よね?)
これで「解決」と思いきや、この文は正常に動作しない。
なぜなら、!aの時のreturnは、aではなく、
() => { a['endAge'] = c; return a; }
というfunctionがreturnになってしまうためだ。
functionそのものではなくfunctionの結果が欲しいのだ。
なにで発見したのか忘れてしまったが、functionの結果を返すようにするには、
(...).call()
で更に囲むと実現できる。
これで正しく動作する。
改めて、完成形の文は以下のようになる。
.reduce((a, c) => !a ? { startAge : c } : (() => { a['endAge'] = c; return a; }).call(), null);
まあ、あまりやりすぎると1行のコードが長くなり醜くなるので、
その辺は臨機応変に。