まず最初に言っておきます。ビルトインオブジェクトにプロパティ、メソッドを追加するのは、たいがい Bad mannerです。やらないでください。
と ことわった上でちょっとだけ遊んでみました。
今現在、|>
はまだ普通には使えないので、代わりといっては何ですが、パイプライン演算子っぽいものを作ってみます。
const _ = Symbol("pipeline")
Object.prototype[_] = function(f){return f(this)}
はい完成。
Object.prototype に [_] というメソッドを追加してみました。自分を関数に適用した結果を返す、みたいなことです。
名前は既存のプロパティ、メソッドとかぶっちゃいけないので、Symbolを使ってみました。
こんな使い方です。
console.log(
[0,1]
[_] (x=>x.map(e=>e*2)) // [0, 2]
[_] (x=>x.reduce((acc,e)=>acc+e,0)) // 2
[_] (x=>x===0) // false
[_] (x=>!x) // true
); // 'true'
ほーらパイプライン演算子に見えてきた!
おしまい。
くれぐれも本番では使いませんように。
「おかしいよ」「そんなことしたら、こんな悪いことがあるぞ」というようなお叱りのコメント、おまちしております。
#追記: これのダメなところと対策
もうちょっと遊んでみます。
ダメなところ
Object.prototype にメソッドを付ければ、すべてのモノに使える、と思ったのが間違いの元。
null[_] // TypeError: Cannot read property 'Symbol(pipeline)' of null
undefined[_] // TypeError: Cannot read property 'Symbol(pipeline)' of undefined
null と undefined には使えませんでした。
なので、実行時にこの疑似パイプラインのチェーンの途中にこれらの値が現れると、エラーで止まる、ということになります。
対策1 : nullとundefinedを適宜、別のものにすりかえる
const thingNull = Symbol("null")
const thingUndefined = Symbol("undefined")
const checkFail = x =>
x===null ? thingNull
: x===undefined ? thingUndefined
: x
const _ = Symbol("pipeline")
Object.prototype[_] = function(f){
const thingThis = this.valueOf()
return checkFail(
f(
thingThis===thingNull ? null
: thingThis===thingUndefined ? undefined
: thingThis
)
)
}
こうしておくと
checkFail(undefined) [_] (x=>x); // Symbol(undefined)
checkFail(null) [_] (n=>n===null); // true
```
のように、最初だけ null/undefined かどうか、チェック checkFail() が必要ですが、あとは適宜ダメなところは別のオブジェクト thingNull/thingUndefined にすりかえながら計算を続行してくれます。
## 対策2 : null, undefined, NaN をまとめて、「計算が失敗した」ことにする
```js:
const Nothing = Symbol("Nothing")
const checkFail = x =>
x===null || x===undefined || Number.isNaN(x) ? Nothing : x
const _ = Symbol("pipeline")
Object.prototype[_] = function(f){
const thingThis = this.valueOf()
return (thingThis===Nothing)? Nothing
: checkFail(f(thingThis))
}
```
対策1と似ていますが、 null/undefined/NaN が現れたら 計算の失敗 Nothing ということにして 以降は計算しないで Nothing を返す、というところが違います。
```js:
checkFail(undefined) [_] (x=>x); // Symbol(Nothing)
checkFail(null) [_] (n=>n===null); // Symbol(Nothing)
checkFail( 1 ) [_] (x=>NaN); // Symbol(Nothing)
```
これで、途中に null/undefined が現れても大丈夫になりました。
おしまい。
くれぐれも本番では使いませんように。