4

したがって、私が知っているのはif、Javascript のステートメントは条件の結果をブール値にキャストし、次のように実行するということです。

if(true) {
    // run this
}

if(false) {
    // do not run this
}

そして、それは機能します。しかし、私がこれを行うと:

if('0' == false) {
    // We get here, so '0' is a falsy value
}

それから私はこれを期待します

if('0') {
    // We don't get here, because '0' is falsy value
}

しかし、代わりに私は得る

if('0') {
    // We *DO* get here, even though '0' is falsy value
}

それで、何が起こっているのですか?どうやら、ifその条件が真または偽の値であるかどうかをチェックしませんが、他の変換を行いますか?

4

4 に答える 4

7

これは、かなり複雑な==ルールを持つ「落とし穴」の 1 つにすぎません。

x と y が値である比較 x == y は、true または false を生成します。このような比較は、次のように実行されます。

(4) Type(x) が Number で Type(y) が String の場合、x == ToNumber(y) の比較結果を返します。

(5) Type(x) が String で Type(y) が Number の場合、ToNumber(x) == y の比較結果を返します。

(6) Type(x) が Boolean の場合、比較 ToNumber(x) == y の結果を返します。

(7) Type(y) が Boolean の場合、比較 x == ToNumber(y) の結果を返します。

この場合、それ'0' == falseは最初に do を強制され'0' == 0(ルール #7 によって)、次に 2 回目のパススルーで0 == 0(ルール #5 によって) 強制され、結果は true になります。

この特定のケースは、 (予想されるように)false ~> 0代わりにあるため、やや注意が必要です。'0' ~> trueただし、'0'それ自体は true-y 値であり、動作は上記のルールで説明できます。テストで厳密な真偽等価 (厳密等価とは異なります) を、等価中の暗黙の変換なしで行うには、次のことを考慮してください。

!!'0' == !!false

(すべての値:!falsey -> trueおよび!truthy -> false.)

于 2013-05-08T21:56:04.553 に答える
3

これ:

if('0') {
    // We *DO* get here, even though '0' is falsy value
}

文字列がゼロかどうかではなく、null または空かどうかを確認します。空でない文字列はすべて真実です。

これを行う場合:

if('0' == false) {
    // We get here, so '0' is a falsy value
}

2 つのオペランドの型を一致させるために、明示的な型変換を JS エンジンに要求しています。これは、1 つのオペランドがそれ自体で真であるかどうかを尋ねるのとは異なります。

一般に、非常に複雑な型強制ルールを完全に理解しているか、型強制ルールを完全に理解しているために、すべてのケースで何が起こるかを正確に知っている場合に、ほぼ常に型強制を使用===し、型強制のみを許可すると、予期しない結果が少なくなることがわかります。!==タイプが存在し、それらの特定のケースを理解します。

于 2013-05-08T21:48:06.780 に答える
3

if ('0' == false):

Javascript は と呼ばれるものを実行していますtype coercion

そのリンクのルールに従うと、ルール 7 になります。

Type(y) が Boolean の場合、比較の結果を返します x == ToNumber(y)

ToNumber(false) を呼び出すと、数値の 0 が返されます。結果は意味をなすようになりましたが、まだ文字列と数値があるため、まだ完了していません。プロセスが再び開始され、今回はルール 5 に該当します。

Type(x) が String で Type(y) が Number の場合、比較の結果を返す ToNumber(x) == y: "2" == 2

今度は、左側の「0」が数値 0 に変換されます。これで、ようやく 2 つの数値を比較できます。0 は 0 に等しいので、結果は true です。'0'ただし、文字列は比較される前に強制されているため、これは文字列の真実/偽りの性質についてまったく意味がないことに注意することが重要です。

if('0')

この場合、比較はありません。単一の値が「真」か「偽」かを知りたいだけです。文字列はそれ自体のメリットで真または偽として評価できるため、型強制は使用されません。以前と同じリンクのルールを使用すると、次の情報が見つかります。

JavaScript だけでなく、JavaScript にも、いわゆる偽値があります。これらはそれぞれ、0、null、undefined、false、""、NaN です。空の文字列は空であることに注意してください。例としてphpとは異なり、「0」は真と見なされます

引用符は特に「0」文字列を呼び出すため、特に役立ちますが、これは必須ではありません。文字列の内容は評価されず、強制も実行されないため、空の文字列は偽であり、それ以外の文字列は真であることがわかっていれば十分です。0は偽の値かもしれませんが、数値に強制するのではなく文字列を評価し、'0'何らかの値を持っているため、それでも真です。

于 2013-05-08T21:53:59.387 に答える
1

Javascript 演算子==は型変換を行い、基本的に役に立ちません。避けてください。

例えば:

  • [][] == false真実ですが、真実です
  • 1 == "1"[1] == "1"[[1]] == "1"すべて真です
  • [1] == [[1]]しかし、偽です

ルールは非常に奇妙です。たとえば、最初のケースで[]""、これは数値に変換され、値は に変換されます0falseも数値に変換され0ます。したがって、最終的に比較すると同等になります。

ただし、空の文字列から数値への変換では が得られますが0、の結果は であることにparseInt("")注意してくださいNaN

PS: 本当の楽しみは、それが[30,20,10,3,2,1].sort()返されることを発見したときです[1,10,2,20,3,30](はい... 数字、はい、辞書順で)。いいえ、冗談ではありません。

于 2013-05-08T22:04:43.300 に答える