これが、比較演算子がオブジェクトに対して機能する方法です。
var a = {}, b = {};
a === b; //false
a == b; //false
a > b; //false
a < b; //false
var c = { valueOf : function () { return 0; } };
var d = { valueOf : function () { return 1; } };
c === d; //false
c == d; //false
c > d; //false
c < d; //true
フードの下
(一種)
パート1:平等
これが最も簡単な部分です。抽象的等式(==
、spec)と厳密な等式(===
、spec )の両方が、同じオブジェクトを参照しているかどうかをチェックします(参照の比較のようなもの)。この場合、彼らは明らかにそうではないので、彼らは答えますfalse
(==
スペックステップ10、===
スペックステップ7)。
したがって、どちらの場合も:
b1 == b2 //false
b1 === b2 //false
パート2:比較は反撃します
ここに興味深い部分があります。<
関係演算子(および>
)がどのように定義されているかを見てみましょう。2つの場合のコールチェーンをたどってみましょう。
x = b1 //<Buffer aa>
y = b2 //<Buffer ab>
//11.8.5 The Abstract Relational Comparison Algorithm (http://es5.github.com/#x11.8.5)
Let px be the result of calling ToPrimitive(x, hint Number).
Let py be the result of calling ToPrimitive(y, hint Number).
//9.1 ToPrimitive (http://es5.github.com/#x9.1)
InputType is Object, therefore we call the internal [[DefaultValue]] method with hint Number.
//8.12.8 [[DefaultValue]] (hint) http://es5.github.com/#x8.12.8
We try and fetch the object's toString method. If it's defined, call it.
そして、ここで私たちはクライマックスに達しました:バッファのtoString
メソッドは何ですか?答えは、node.jsの内部の奥深くにあります。必要に応じて、それを持っています。私たちが簡単に見つけることができるのは、実験によるものです。
> b1.toString()
'�'
> b2.toString()
'�'
さて、それは役に立ちませんでした。<
抽象関係比較アルゴリズム(の大きな名前)には、文字列を処理するためのステップがあることに気付くでしょう。それらを数値(charコード)に変換するだけです。そうしよう:
> b1.toString().charCodeAt(0)
65533
> b2.toString().charCodeAt(0)
65533
65533は重要な番号です。これは、2つの二乗の合計です142^2 + 213^2
。また、「何が起こったのかわからない」という意味のUnicode置換文字でもあります。そのため、16進数に相当するものはFFFDです。
明らかに、、65533 === 65533
そう:
b1 < b2 //is
b1.toString().charCodeAt(0) < b2.toString().charCodeAt(0) //is
65533 < 65533 //false
b1 > b2 //following same logic as above, false
そしてそれはそれです。
おい、一体何?
さて、私の説明の努力がよく考えられていなかったので、これは混乱していたに違いありません。要約すると、次のようになりました。
バッファを作成しました。Benjamin Gruenbaumは、次のようにしてテストケースを再現するのを手伝ってくれました。
var b1 = new Buffer([170]), b2 = new Buffer([171]);
コンソールに出力するとき、値は同等の16進数に変換されます(Buffer#inspectを参照)。
170..toString(16) === 'aa'
171..toString(16) === 'ab'
ただし、内部的には、それらは無効な文字を表しています(16進エンコードではないため、繰り返しになりますが、実装の本質を自由に掘り下げることができます。皮肉なことに)。したがって、文字列に変換すると、Unicode置換文字で表されます。
それらは異なるオブジェクトであるため、すべての等式演算子はを返しfalse
ます。
ただし、作業の方法が少ないため、または大きいため、比較のために文字列(および数値)に変換されました。ポイント#3に照らして、それは同じ値です。したがって、それらを互いに小さくしたり大きくしたりすることはできず、になりfalse
ます。
最後に、あなたの顔に笑顔を置くために:
b1 <= b2 //true
b1 >= b2 //true