私は読んでいます Douglas CrockfordのJavaScript:The Good Parts 、そして私はこの奇妙な例に出くわしました。私にとっての感覚:
'' == '0' // false
0 == '' // true
0 == '0' // true
false == undefined // false
false == null // false
null == undefined // true
著者はまた、「==
と!=
を絶対に使用しないでください。代わりに、常に===
と!==
を使用してください」と述べています。しかし、彼はなぜ上記の行動が見られるのか説明していませんか?だから私の質問は、なぜ上記の結果がそのままなのかということです。 JavaScriptでは推移性は考慮されていませんか?
'' == '0' // false
左側は空の文字列で、右側は1文字の文字列です。 2つの同一でない文字列を比較しているため、これらは誤りです(ありがとう Niall )。
0 == '' // true
したがって、0
がfalsyであり、空の文字列がfalsyであるため、これが真である理由。
0 == '0' // true
これは少しトリッキーです。仕様では、オペランドが文字列と数値の場合、文字列を数値に強制変換すると規定されています。 '0'
は0
になります。ありがとう smfoote 。
false == undefined // false
値undefined
はJavaScriptで特別であり、null
以外の値と同じではありません。ただし、偽りです。
false == null // false
繰り返しますが、null
は特別です。 undefined
と等しいだけです。また、偽りです。
null == undefined // true
null
とundefined
は似ていますが、同じではありません。 null
はnothingを意味し、undefined
は設定されていないか存在しない変数の値です。それらの値が等しいと見なされることは、ある意味で理にかなっています。
本当に混乱したい場合は、これを確認してください...
'\n\r\t' == 0
空白のみで構成される文字列は、0に等しいと見なされます。
ダグラス・クロックフォードはたくさんの推薦をします、しかしあなたはそれらを福音としてとらえる必要はありません。 :)
T.J。Crowder これらの同等性テストの背後にある全体像を知るために ECMAScript言語仕様 を研究することを提案します。
参考文献?
仕様 。
この質問への答えは、JavaScriptが強制を処理する方法と関係があります。 _==
_の場合、 文字列は強制的に数値になります 。したがって:
_'' == '0'
_は_'' === '0'
_と同等です(どちらも文字列であるため、強制は必要ありません)。
_0 == ''
_は_0 === 0
_と同等です。これは、文字列_''
_が数値_0
_(math.abs('') === 0
)になるためです。
_0 == '0'
_は、同じ理由で_0 === 0
_と同等です。
_false == undefined
_は_0 === undefined
_と同等です。これは、タイプが一致しない場合、JavaScriptがブール値を数値に強制変換するためです。
_false == null
_は、同じ理由で_0 === null
_と同等です。
仕様にそのように記載されているため、_null == undefined
_はtrueです。
この質問をしてくれてありがとう。 _==
_についての私の理解は、それを研究したことではるかに良くなりました。
実際には、==
とまったく同じように動作するJavaScript関数を記述して、その動作についての洞察を得ることができます。
ここで私が意味することを示すために、その関数は次のとおりです。
// loseEqual() behaves just like `==`
function loseEqual(x, y) {
// notice the function only uses "strict" operators
// like `===` and `!==` to do comparisons
if(typeof y === typeof x) return y === x;
if(typeof y === "function" || typeof x === "function") return false;
// treat null and undefined the same
var xIsNothing = (y === undefined) || (y === null);
var yIsNothing = (x === undefined) || (x === null);
if(xIsNothing || yIsNothing) return (xIsNothing && yIsNothing);
if(typeof x === "object") x = toPrimitive(x);
if(typeof y === "object") y = toPrimitive(y);
if(typeof y === typeof x) return y === x;
// convert x and y into numbers if they are not already use the "+" trick
if(typeof x !== "number") x = +x;
if(typeof y !== "number") y = +y;
return x === y;
}
function toPrimitive(obj) {
var value = obj.valueOf();
if(obj !== value) return value;
return obj.toString();
}
ご覧のとおり、==
には型変換のための複雑なロジックがたくさんあります。そのため、どのような結果が得られるかを予測するのは困難です。
予期しない結果の例を次に示します。
予期しない真実
[1] == true // returns true
'0' == false // returns true
[] == false // returns true
[[]] == false // returns true
[0] == false // returns true
'\r\n\t' == 0 // returns true
予期しない結論
// IF an empty string '' is equal to the number zero (0)
'' == 0 // return true
// AND the string zero '0' is equal to the number zero (0)
'0' == 0 // return true
// THEN an empty string must be equal to the string zero '0'
'' == '0' // returns **FALSE**
特殊機能を持つオブジェクト
// Below are examples of objects that
// implement `valueOf()` and `toString()`
var objTest = {
toString: function() {
return "test";
}
};
var obj100 = {
valueOf: function() {
return 100;
}
};
var objTest100 = {
toString: function() {
return "test";
},
valueOf: function() {
return 100;
}
};
objTest == "test" // returns true
obj100 == 100 // returns true
objTest100 == 100 // returns true
objTest100 == "test" // returns **FALSE**