web-dev-qa-db-ja.com

JavaScriptでは、なぜ「0」がfalseに等しいのですが、「if」でテストした場合、それ自体はfalseではありません。

以下は、Javascriptの"0"がfalseであることを示しています。

>>> "0" == false
true

>>> false == "0"
true

では、なぜ次のように表示されるのですか?"ha"

>>> if ("0") console.log("ha")
ha
212

これは、明示的に"0" == falseを実行すると、両側が数値に変換され、次にが比較されるためです

if ("0") console.log("ha")を実行すると、文字列値がテストされます。空でない文字列はtrueで、空の文字列はfalseです。

等しい(==)

2つのオペランドが同じ型ではない場合、JavaScriptはオペランドを変換してから厳密な比較を適用します。いずれかのオペランドが数値またはブール値の場合、可能であればオペランドは数値に変換されます。それ以外の場合、一方のオペランドが文字列の場合、可能であればもう一方のオペランドは文字列に変換されます。 両方のオペランドがオブジェクトの場合、JavaScriptは、オペランドがメモリ内の同じオブジェクトを参照するときに等しい内部参照を比較します。

(From 比較演算子 (Mozilla Developer Network内))

238
jdi

問題を表示している表:

truthy if statement

と== truthy comparisons of all object types in javascript

物語の道徳的使用=== strict equality displaying sanity

テーブル生成クレジット: https://github.com/dorey/JavaScript-Equality-Table

325
Joe

仕様通りです。

 12.5 ifステートメント
 ..... 
 
 2。 ToBoolean(GetValue(exprRef))がtrueの場合、
最初のステートメントを評価した結果を返します。 
 3。そうでなければ、
 .... 

仕様によると、ToBooleanは

抽象演算ToBooleanは、表11に従って、引数をBoolean型の値に変換します。

そしてそのテーブルは文字列についてこれを言っています:

enter image description here

引数が空の文字列(長さがゼロ)の場合、結果は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を使用して評価する場合は===を使用します(「厳密な」等価演算子とも呼ばれます)。

36
Incognito

文字列"0"が誤っているのはPHPです(false-boolean-contextで使用された場合)。 JavaScriptでは、空でない文字列はすべて真実です。

トリックは、ブール値に対する==はブール値のコンテキストでは評価されず、数値に変換されます。文字列の場合は10進数として解析されます。そのため、真偽値のtrueではなくNumber 0を取得します。

これは本当に貧弱な言語設計であり、残念な==演算子を使わないようにする理由の1つです。代わりに===を使用してください。

12
bobince
// 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.
7
Thava

0を囲む引用符はそれを文字列にし、それはtrueと評価されます。

引用符を削除するとうまくいくはずです。

if (0) console.log("ha") 
4
Jason Gennaro

これはすべてECMAの仕様によるものです...ここで指定されているルールによる"0" == falsehttp://ecma262-5.com/ELS5_HTML.htm#Section_11.9.3 ...そしてここで指定された規則のためにif ('0')はtrueと評価されます http://ecma262-5.com/ELS5_HTML.htm#Section_12.5

1
Narendra Yadala

"if"式は真実性をテストし、二重等号は型に依存しない等価性をテストします。他の人が指摘しているように、文字列は常に真実です。 double-equalが両方のオペランドの真偽をテストしてから結果を比較している場合は、直感的に想定していた結果、つまり("0" == true) === trueが得られます。 Doug Crockfordが彼の優れたJavaScript:The Good Partsで述べているように、 "[==そのオペランドの型を強制する規則]は複雑で思い出に残るものです。推移性の欠如は憂慮すべきです。 「一方のオペランドは他方に一致するように型強制され、 "0"は数値のゼロとして解釈されることになります。つまり、ブール値に強制されるとfalseに相当します(またはfalseはゼロに相当します)。数に強制されたとき)。

1
Jollymorphic

==等号演算子は、引数を数値に変換した後に評価します。 つまり、文字列ゼロ "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

`

1
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/ を参照してください。

0
AngusC