think49のコメント: == と 型変換の関係性 (スコア 1) 60
JavaScriptで「(a ==1 && a== 2 && a==3)」という式の結果を真にするにはどうすればいいのか、StackOverflowで議論されている。
まず、`Object.prototpe.valueOf` を使う方法を考えました。
var a = {valueOf: (value => (() => value++))(1)};
console.log(a == 1 && a == 2 && a == 3); // true
このコードが気持ち悪いと思う原因は、`==` にあると考えます。
`==` は両辺の型が不一致の場合に可能な限り型を合わせようとする為、Object型をPremitive型に変換し、valueOf() による型変換を許してしまいます。
上記コードは下記の疑似コードとほぼ同じ動作になっています。
var a = {valueOf: (value => (() => value++))(1)};
console.log(Number(a) === 1 && Number(a) === 2 && Number(a) === 3); // true
ですので、両辺の型の不一致を `false` と評価する `===` に変更する事で、このテクニックは使えなくなります。
var a = {valueOf: (value => (() => value++))(1)};
console.log(a === 1 && a === 2 && a === 3); // false
「こんなJavaScriptは気持ち悪い」と評価されるきらいがありますが、本来、この機能は Primitive 型の機能を持ったオブジェクトをユーザが自由に生成できる意図があるように思います。
Number 型は `Number.prototype` にあるメソッドをプロトタイプチェーンの原則によって使えますが、Number 型の機能を拡張したい場合に `Number.prototype` を拡張するのは影響範囲が大きすぎる為、一般には使われません。
そこで、`CustomNumber.prototype` を拡張して、ユーザ定義の Number 型であるかのようなオブジェクトを生成したいとします。
valueOf, toString メソッドを使う事で、ある程度はそのようなオブジェクトを生成する事が出来ます。
JavaScriptの一部の演算子は Primitive 型に変換する事で役割を果たす為、Primitive 値をコントロールできるといろいろと都合が良いのです。
そのような「特別なオブジェクト」を生成したい、と考えたときに「JavaScriptは素晴らしい」と感じられるのかもしれません。