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


232

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

>>> "0" == false
true

>>> false == "0"
true

では、なぜ次のように出力するの"ha"ですか?

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

47
"0"文字列であり、空ではないため、trueと評価されます。
デジタルプレーン

8
"0" === false [...] false

3
Angus Crollの真実をJavaScriptで確認してください。javascriptweblog.wordpress.com/2011/02/07/...
timrwood

8
'0'==falseしかし、「0」は誤った値ではありません(はい、Javascriptは奇妙な場合があります)
Linsey

5
@Linsey:「虚偽」と「真実」の全体は、値がブール値に変換される方法を説明することのみを目的としていました。2つの値を==で比較する場合、それらブール値に変換されないため、適用されません。(変換の規則では、数値への変換が優先されるようです。)
millimoose

回答:


251

あなたが明示的に行うとき、その理由がある"0" == false、両側が数値に変換され、そしてその後、比較が行われます。

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

等しい(==)

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

比較演算子から Mozilla Developer Networkの)


348

問題を表示する表:

真実のifステートメント

および== JavaScriptのすべてのオブジェクトタイプの真実の比較

ストーリーのモラル=== 正格を表示する厳密な平等

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



3
これから、厳密な比較演算子を使用しないと誰かが言ったら、私はこれらのテーブルに直面して彼を泣かせます。それでもコンセプトを理解しているかどうかはわかりませんNaN。私が意味する、typeof NaN // numberしかしNaN === NaN // false、うーん...
ユストゥス・ローミン

4
私の友人がf.cl.ly/items/3b0q1n0o1m142P1P340P/javascript_equality.htmlを作成しました -上記と同じグラフですが、少し読みやすくなっています。
Lucy Bain、2014

@JustusRomijnを表す複数の値があるNaNため、2つのNaNを比較すると、それらは異なる値になります(私は推測します)。ここで最初の引用を読んでください
cychoi

4
これらのテーブルに誤りがあります。どちら=====のためのオペレータ[]{}[[]][0]および[1]値がtrueに評価されません。つまり[] == [][] === []また偽です。
Herbertusz

38

仕様による。

12.5 ifステートメント 
.....

2. ToBoolean(GetValue(exprRef))がtrueの場合、 
a。最初のステートメントの評価結果を返します。
3.それ以外の場合 
....

仕様によると、ToBooleanは

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

そしてその表は文字列についてこれを述べています:

ここに画像の説明を入力してください

引数が空の文字列(長さがゼロ)の場合、結果はfalseです。そうでなければ結果は真です

ここで、なぜ"0" == false抽象演算子から値を取得する等値演算子を読み取る必要があるのかを説明するGetValue(lref)ために、右側と同じように一致します。

これは、この関連部分を次のように説明しています。

IsPropertyReference(V)の場合、 
a。HasPrimitiveBase(V)がfalseの場合、getをbaseの[[Get]]内部メソッドとし、それ以外の場合はgetとします。
以下で定義される特別な[[Get]]内部メソッドである。 
b。この値としてbaseを使用してget内部メソッドを呼び出し、渡した結果を返します
引数のGetReferencedName(V)

または、言い換えると、文字列にはプリミティブベースがあり、内部のgetメソッドをコールバックして最終的にfalseに見えます。

GetValueオペレーションを使用して物事を==評価したい場合はuse 、を使用して評価したい場合はToBoolean、use ===(「厳密な」等価演算子とも呼ばれます)


"a string has a primitive base, which calls back the internal get method and ends up looking false"これはすべての文字列に当てはまりますか?
aziz punjani 2011

@Interstellar_Coder Section 8.12.3: [[Get]] (P)は、それがどのように機能するかを説明します。これは、文字列が0の場合にのみ当てはまります。これは、他の内部呼び出しの束を実行し、最終的にGetOwnProperty「whatever」がデータプロパティであると判断し、その値までずっと戻るためです。これが、「0」が偽で、「何とか」が真である理由です。Yahoo開発者向け劇場でDouglas Crockfordのビデオをいくつかチェックしてください。彼はJavaScriptの「真実性」について、私よりも少し複雑ではないと説明しています。「真実」と「虚偽」の意味を理解すれば、ボビンスの答えをすぐに理解できます。
シークレット

1
仕様はどこにありますか?
user985366 2016年

12

これは、文字列"0"が偽のPHP です(boolean-contextでfalseのときに使用)。JavaScriptでは、空ではない文字列はすべて真実です。

トリックは==、ブール値に対してブール値に対して評価されず、数値に変換され、文字列の場合は10進数として解析されます。つまり0、真偽値のブール値ではなく、数値を取得しますtrue

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


7
// 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.

4

引用符で囲む0と文字列になり、trueと評価されます。

引用符を削除すると、機能するはずです。

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

「正しく動作させる」方法ではなく、正しいのですが、質問は「なぜそのように動作したのですか?」
非極性14年

2

すべて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


誰かが仕様をサイトに移植したことを知りませんでした...それは素晴らしいです!もうPDFは必要ありません。
シークレットモード、2011

1

「if」式は真実かどうかをテストしますが、double-equalはタイプに依存しない同値かどうかをテストします。他の人が指摘したように、文字列は常に真実です。double-equalが両方のオペランドの真実性をテストし、結果を比較していた場合、直感的に想定していた結果が得られます("0" == true) === true。Doug Crockfordが彼の優れたJavaScript:Good Partsで述べているように、「[==オペランドのタイプを強制する]ルールは複雑で、記憶に残るものではありません...推移性の欠如は憂慮すべきです」。オペランドの1つがもう一方と一致するように型強制され、「0」が数値のゼロとして解釈されることになると言うだけで十分です。


1

==等価演算子は、引数を数値に変換してから評価します。 文字列のゼロ「0」Numberデータ型とブールfalseに変換されますので、番号を0に変換される ので、

"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

これは、JavaScriptがブールコンテキストとコードで型強制を使用するためです。

if ("0") 

ブールコンテキストではtrueに強制されます。

ブール値のコンテキストでtrueに強制されるJavascriptには他の真実な値があるため、ifブロックは次のようになります:-

if (true)
if ({})
if ([])
if (42)
if ("0")
if ("false")
if (new Date())
if (-42)
if (12n)
if (3.14)
if (-3.14)
if (Infinity)
if (-Infinity)

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.