以下は、Javascriptの"0"
がfalseであることを示しています。
>>> "0" == false
true
>>> false == "0"
true
では、なぜ次のように表示されるのですか?"ha"
>>> if ("0") console.log("ha")
ha
これは、明示的に"0" == false
を実行すると、両側が数値に変換され、次にが比較されるためです。
if ("0") console.log("ha")
を実行すると、文字列値がテストされます。空でない文字列はtrue
で、空の文字列はfalse
です。
等しい(==)
2つのオペランドが同じ型ではない場合、JavaScriptはオペランドを変換してから厳密な比較を適用します。いずれかのオペランドが数値またはブール値の場合、可能であればオペランドは数値に変換されます。それ以外の場合、一方のオペランドが文字列の場合、可能であればもう一方のオペランドは文字列に変換されます。 両方のオペランドがオブジェクトの場合、JavaScriptは、オペランドがメモリ内の同じオブジェクトを参照するときに等しい内部参照を比較します。
(From 比較演算子 (Mozilla Developer Network内))
仕様通りです。
12.5 ifステートメント ..... 2。 ToBoolean(GetValue(exprRef))がtrueの場合、 最初のステートメントを評価した結果を返します。 3。そうでなければ、 ....
仕様によると、ToBooleanは
抽象演算ToBooleanは、表11に従って、引数をBoolean型の値に変換します。
そしてそのテーブルは文字列についてこれを言っています:
引数が空の文字列(長さがゼロ)の場合、結果はfalseです。そうでなければ結果は真です
さて、なぜ"0" == false
が等価演算子を読むべきなのかを説明するために、それは抽象演算GetValue(lref)
からその値が得られることを示しています。
この関連部分は次のように説明されています。
IsPropertyReference(V)の場合、 a。 HasPrimitiveBase(V)がfalseの場合、getをbaseの[[Get]]内部メソッドとし、それ以外の場合はget を以下で定義される特別な[[Get]]内部メソッドとします。 b。 thisの値としてbaseを使用してget internalメソッドを呼び出し、引数として GetReferencedName(V)を渡した結果を返します。
あるいは言い換えれば、文字列は基本的な基底を持ち、これは内部のgetメソッドを呼び戻して偽になります。
GetValue操作を使用して評価する場合は==
を使用し、ToBoolean
を使用して評価する場合は===
を使用します(「厳密な」等価演算子とも呼ばれます)。
文字列"0"
が誤っているのはPHPです(false-boolean-contextで使用された場合)。 JavaScriptでは、空でない文字列はすべて真実です。
トリックは、ブール値に対する==
はブール値のコンテキストでは評価されず、数値に変換されます。文字列の場合は10進数として解析されます。そのため、真偽値のtrue
ではなくNumber 0
を取得します。
これは本当に貧弱な言語設計であり、残念な==
演算子を使わないようにする理由の1つです。代わりに===
を使用してください。
// I usually do this:
x = "0" ;
if (!!+x) console.log('I am true');
else console.log('I am false');
// Essentially converting string to integer and then boolean.
0
を囲む引用符はそれを文字列にし、それはtrueと評価されます。
引用符を削除するとうまくいくはずです。
if (0) console.log("ha")
これはすべてECMAの仕様によるものです...ここで指定されているルールによる"0" == false
http://ecma262-5.com/ELS5_HTML.htm#Section_11.9.3 ...そしてここで指定された規則のためにif ('0')
はtrueと評価されます http://ecma262-5.com/ELS5_HTML.htm#Section_12.5
"if"式は真実性をテストし、二重等号は型に依存しない等価性をテストします。他の人が指摘しているように、文字列は常に真実です。 double-equalが両方のオペランドの真偽をテストしてから結果を比較している場合は、直感的に想定していた結果、つまり("0" == true) === true
が得られます。 Doug Crockfordが彼の優れたJavaScript:The Good Partsで述べているように、 "[==そのオペランドの型を強制する規則]は複雑で思い出に残るものです。推移性の欠如は憂慮すべきです。 「一方のオペランドは他方に一致するように型強制され、 "0"は数値のゼロとして解釈されることになります。つまり、ブール値に強制されるとfalseに相当します(またはfalseはゼロに相当します)。数に強制されたとき)。
==等号演算子は、引数を数値に変換した後に評価します。 つまり、文字列ゼロ "0"は数値データ型に変換され、ブール値のfalseは数値0に変換されます。 So
"0" == false // true
同じことが `にも当てはまります
false == "0" //true
===厳密な等価検査は、元のデータ型で引数を評価します。
"0" === false // false, because "0" is a string and false is boolean
同じことが当てはまります。
false === "0" // false
に
if("0") console.log("ha");
文字列 "0"は引数と比較されていません。文字列は引数と比較されるまで、または引数と比較されない限り真の値です。まさにこんな感じです
if(true) console.log("ha");
しかし
if (0) console.log("ha"); // empty console line, because 0 is false
`
if (x)
javaScriptの内部toBooleanを使用してxを強制します(http://es5.github.com/#x9.2)
x == false
内部のtoNumber強制(http://es5.github.com/#x9.3)またはオブジェクトのtoPrimitive(http://es5.github.com/#x9.1)を使用して両側を強制します。
完全な詳細については http://javascriptweblog.wordpress.com/2011/02/07/truth-equality-and-javascript/ を参照してください。