なぜ「null> = 0 && null <= 0」だが「null == 0」ではないのですか?


142

変数の型が1の場合は変数の値を1だけ増分し、numberそうでない場合は変数に0を割り当てるルーチンを作成するnull必要がありましたundefined

最初の実装はv >= 0 ? v += 1 : v = 0、数値ではないものはすべて算術式を偽にすると考えたためでしたが、null >= 0真と評価されたため、それは間違っていました。次にnull、0のように動作することを学び、次の式はすべてtrueと評価されます。

  • null >= 0 && null <= 0
  • !(null < 0 || null > 0)
  • null + 1 === 1
  • 1 / null === Infinity
  • Math.pow(42, null) === 1

もちろん、nullis 0でnull == 0はありません。false と評価されます。これは、一見トートロジー的な表現を(v >= 0 && v <= 0) === (v == 0)誤ったものにします。

null実際には0ではないのに、なぜ0のようなものですか?


3
彼はJavascriptについて話している。あなたの例はPHPです。PHPでは、operator ==は特別な方法で値を比較します。"10" == "1e1"(これは真実)のような非常にクレイジーな比較を行うことができます。operator ===を使用した場合、タイプだけでなく値も一致するかどうかをチェックするため、まったく異なる結果が得られます。このリンクを確認してください:php.net/manual/en/language.operators.comparison.php
Pijusn

PHPの「==」演算子は、実際には「特別な」方法で機能します。
2ビットの錬金術師

あなたの要件は1ではなく0でカウントを開始した場合、最初はインクリメントカウンタには本当に簡潔な方法は、どちらかがありますnullundefinedc = -~c // Results in 1 for null/undefined; increments if already a number
ATES Goral

1
undefined初期化されていない変数の変数値です。null一方、は空のオブジェクト値であり、数値と混在させないでください。null数値と組み合わせるべきではないので、nullは数値のように振る舞う必要はありません。
Matthew

1
@AtesGoral-簡潔ですが、自明ではありません。自明ではないことをするときはいつでも、コードの内容を説明するコメントを追加してください。ほとんどの状況では、明快さを最小限のパフォーマンス向上と交換することを考えると、それは「時期尚早の最適化」と見なします。
ToolmakerSteve

回答:


207

あなたの本当の質問は次のようです:

なぜ:

null >= 0; // true

だが:

null == 0; // false

実際に起こることは、より大きいか等しい演算子>=)が型強制(ToPrimitive)を実行し、ヒント型がであるということですNumber。実際には、すべての関係演算子がこの動作をします。

null等号演算子==)によって特別な方法で処理されます。簡単に言うと、次のことのみを強制undefinedます。

null == null; // true
null == undefined; // true

値は、次のようなfalse'''0'、および[]、それらのすべてがゼロに数値型の強制の対象を強制されています。

このプロセスの詳細は、抽象等値比較アルゴリズム抽象関係比較アルゴリズムで確認できます。

要約すれば:

  • 関係比較:両方の値がタイプStringでない場合、両方ToNumberで呼び出されます。これは、+前にaを追加するのと同じ0です。

  • 等価比較:ToNumber文字列、数値、ブール値のみを呼び出します。


1
こんにちはCMS、説明に従ってnullプリミティブは0なので、0> = 0はtrueを返し、==はfalseを返します。ただし、ecmaアルゴリズムに従ってType(x)がObjectでType(y)がStringまたはNumberの場合、比較の結果を返すToPrimitive(x)== y。次に、これはtrueを返すはずです。説明してください
bharath muppa

私には答えが用意されていません答え - null is treated in a special way by the Equals Operator (==). In a brief, it only coerces to undefined:-と何を?なぜ説明できますかnull >= 0?:)
Andrey Deineko

@bharathmuppa @ andrey-deineko:CMSの残りの答えはここにあります: ポイント3で説明する抽象リレーショナル比較アルゴリズム。両方の値が文字列型でない場合、ToNumberは両方で呼び出されます。これは、+前にaを追加するのと同じ0です。Equalityは、文字列、数値、ブール値に対してのみToNumberを呼び出します。
Michael Liquori

7
良い説明ですが、私はそれが好きではありません。どの言語でも(x == 0 || x> 0)は(x> = 0)と同等です。javascriptは愚かな言語です。
John Henckel

1
これは単に仕様上のバグであり(数学的には間違っているため)、何百万ものWebサイトがnull比較に依存しているため、何もする必要はありません^^ '
mahieddine

14

問題の可視性をさらに向上させるために質問を拡張したいと思います。

null >= 0; //true
null <= 0; //true
null == 0; //false
null > 0;  //false
null < 0;  //false

それは意味がありません。人間の言語と同様に、これらのことは暗記する必要があります。


1
上記のように、==がnullを処理する方法を例外として説明できます。それ以外の場合は、Number(nulll)を使用してnullが0に変換されます
Sourabh Ranka

5

JavaScriptには、厳密な比較と型変換の両方の比較があります

null >= 0;正しいが (null==0)||(null>0)間違っている

null <= 0;正しいが(null==0)||(null<0)間違っている

"" >= 0 また本当です

リレーショナル抽象比較(<=、> =)の場合、オペランドは最初にプリミティブに変換され、次に同じ型に変換されてから比較されます。

typeof null returns "object"

タイプがオブジェクトの場合、javascriptはオブジェクトをストリング化しようとします(つまりnull)。次の手順が実行されます(ECMAScript 2015)。

  1. PreferredType渡されなかった場合は、hint「デフォルト」とします。
  2. それ以外の場合PreferredTypehint文字列、hint「文字列」とします。
  3. それ以外PreferredTypehint数値hintです。「数値」としましょう。
  4. してみましょうexoticToPrimことGetMethod(input, @@toPrimitive)
  5. ReturnIfAbrupt(exoticToPrim)
  6. exoticToPrimが未定義でない場合は、
    a)結果をとしますCall(exoticToPrim, input, «hint»)
    b)ReturnIfAbrupt(result)
    c)Type(result)がオブジェクトでない場合、結果を返します。
    d)TypeError例外をスローします。
  7. hintが「デフォルト」の場合、hint「数値」とする。
  8. リターンOrdinaryToPrimitive(input,hint)

ヒントに使用できる値は、「デフォルト」、「数値」、および「文字列」です。日付オブジェクトは、「デフォルト」を「文字列」と同等として扱うという点で、組み込みECMAScriptオブジェクトの中で一意です。 他のすべての組み込みECMAScriptオブジェクトは、「デフォルト」を「数値」と同等のものとして扱います。(ECMAScript 20.3.4.45

したがってnull、0に変換すると思います。


1

同じ問題がありました!!。現在、私の唯一の解決策は分離することです。

var a = null;
var b = undefined;

if (a===0||a>0){ } //return false  !work!
if (b===0||b>0){ } //return false  !work!

//but 
if (a>=0){ } //return true !

代わりに次のようにすると、より明確になる場合がありますif (a!=null && a>=0)。これは、>=「aがnullである可能性がある(または未定義であり、これも '== null'である)可能性がある」という理由を明確にします。
ToolmakerSteve

0
console.log( null > 0 );  // (1) false
console.log( null == 0 ); // (2) false
console.log( null >= 0 ); // (3) true

数学的には、それは奇妙です。最後の結果では、「nullはゼロ以上」と示されているため、上記の比較の1つではtrueでなければなりませんが、両方ともfalseです。

その理由は、等価性チェック==と比較の> < >= <=動作が異なるためです。比較はnullを数値に変換し、として扱い0ます。(3)null >= 0true(1)であるのnull > 0はそのためですfalse

一方、の等価チェック==undefinednull変換なしで相互に等しく、他のものには等しくないように定義されています。それが(2)null == 0がである理由ですfalse

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