为什么 JavaScript 中的 null 大于 -1,小于 1,但不等于 (==) 为 0?那究竟是什么呢?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13407544/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-26 18:40:32  来源:igfitidea点击:

Why is null in JavaScript bigger than -1, less than 1, but not equal (==) to 0? What is it exactly then?

javascript

提问by Totty.js

From the Google Chrome console:

从 Google Chrome 控制台:

var x = null;
undefined
x > 0
false
x < 0
false
x > -1
true
x < 1
true
x == 1
false
x === 1
false

回答by John Kugelman

When you compare null for equality to 0, the result is false. If you force nullto be interpreted in a numeric context then it is treated like 0 and the result becomes true.

当您将 null 的相等性与 0 进行比较时,结果为 false。如果您强制null在数字上下文中进行解释,则将其视为 0,结果变为真。

You can force it to be numeric by putting +in front, or by using numeric operators like <, <=, >, and >=. Notice how null >= 0and null <= 0are both true.

你可以迫使它通过将是数字+,或通过使用数字运营商如在眼前<<=>,和>=。注意如何null >= 0null <= 0都是真的。

> null == 0
false
> +null == 0
true
> null >= 0
true
> null <= 0
true


The ECMAScript Language Specificationdefines when a so-called "ToNumber" conversion is performed. When it is, null and false are both converted to 0.

ECMAScript的语言规范当执行所谓的“ToNumber”的转换定义。如果是,则 null 和 false 都转换为 0。

§9.1 Type Conversion and Testing:

Table 14 — To Number Conversions

Argument Type     Result
-------------     ------
Undefined         Return NaN
Null              Return +0
Boolean           Return 1 if argument is true. Return +0 if argument is false.
Number            Return argument (no conversion).
String            See grammar and note below.

§9.1 类型转换和测试

表 14 — 数字转换

Argument Type     Result
-------------     ------
Undefined         Return NaN
Null              Return +0
Boolean           Return 1 if argument is true. Return +0 if argument is false.
Number            Return argument (no conversion).
String            See grammar and note below.

Knowing when the ToNumber conversion is applied depends on the operator in question. For the relational operators <, <=, >, and >=see:

知道何时应用 ToNumber 转换取决于相关的运算符。对于关系运算符<<=>,并>=请参阅:

§11.8.5 The Abstract Relational Comparison Algorithm:

The comparison x < y, where x and y are values, produces true, false, or undefined(which indicates that at least one operand is NaN). Such a comparison is performed as follows:

  1. Call ToPrimitive(x, hint Number).

  2. Call ToPrimitive(y, hint Number).

  3. If Type(Result(1)) is String and Type(Result(2)) is String, go to step 16. (Note that this step differs from step 7 in the algorithm for the addition operator + in using and instead of or.)

  4. Call ToNumber(Result(1)).

  5. Call ToNumber(Result(2)).

§11.8.5 抽象关系比较算法

比较x < y(其中 x 和 y 是值)产生truefalseundefined(表示至少一个操作数是NaN)。这样的比较如下:

  1. 调用 ToPrimitive(x, 提示编号)。

  2. 调用 ToPrimitive(y, 提示号码)。

  3. 如果 Type(Result(1)) 为 String 且 Type(Result(2)) 为 String,则转到步骤 16。(注意,此步骤与步骤 7 的加法运算符 + 的算法不同,在于使用 and 代替 or。 )

  4. 调用 ToNumber(Result(1))。

  5. 调用 ToNumber(Result(2))。

The ==operator is different. Its type conversions are described below. Notice how null and false follow different rules.

==操作是不同的。下面描述了它的类型转换。请注意 null 和 false 如何遵循不同的规则。

§11.9.3 The Abstract Equality Comparison Algorithm

The comparison x == y, where x and y are values, produces trueor false. Such a comparison is performed as follows:

1. If Type(x) is different from Type(y), go to step 14.

...

14. If x is nulland y is undefined, return true.

15. If x is undefinedand y is null, return true.

16. If Type(x) is Number and Type(y) is String, return the result of the comparison x == ToNumber(y).

17. If Type(x) is String and Type(y) is Number, return the result of the comparison ToNumber(x) == y.

18. If Type(x) is Boolean, return the result of the comparison ToNumber(x) == y.

19. If Type(y) is Boolean, return the result of the comparison x == ToNumber(y).

20. If Type(x) is either String or Number and Type(y) is Object, return the result of the comparison x == ToPrimitive(y).

21. If Type(x) is Object and Type(y) is either String or Number, return the result of the comparison ToPrimitive(x) == y.

22. Return false.

§11.9.3 抽象相等比较算法

比较 x == y,其中 x 和 y 是值,产生truefalse。这样的比较如下:

1. 如果 Type(x) 与 Type(y) 不同,则转至步骤 14。

...

14. 如果 x 为null且 y未定义,则返回true

15. 如果 x未定义且 y 为null,则返回true

16. 如果Type(x) 是Number,Type(y) 是String,则返回比较结果x == ToNumber(y)。

17. 如果Type(x) 是String 并且Type(y) 是Number,则返回比较结果ToNumber(x) == y。

18. 如果 Type(x) 是 Boolean,则返回 ToNumber(x) == y 的比较结果。

19. 如果 Type(y) 是 Boolean,则返回比较结果 x == ToNumber(y)。

20. 如果 Type(x) 是 String 或 Number 并且 Type(y) 是 Object,则返回比较结果 x == ToPrimitive(y)。

21. 如果 Type(x) 是 Object 并且 Type(y) 是 String 或 Number,则返回比较结果 ToPrimitive(x) == y。

22. 返回false

If you read carefully you can see why false == 0is true but null == 0is false.

如果你仔细阅读,你会明白为什么false == 0是真的,但为什么null == 0是假的。

  • For false == 0, Type(x) is Boolean. This means Step 18's type conversion is applied, and false is converted to a number. ToNumber(false) is 0, and 0 == 0is true, so the comparison succeeds.

  • For null == 0, Type(x) is Null. None of the type checks match so the comparison falls through to Step 22, which returns false. The comparison fails.

  • 对于false == 0,Type(x) 是布尔值。这意味着应用了第 18 步的类型转换,并将 false 转换为数字。ToNumber(false) 为 0,0 == 0为 true,所以比较成功。

  • 对于null == 0,Type(x) 为 Null。没有任何类型检查匹配,因此比较会进入步骤 22,该步骤返回 false。比较失败。

回答by tmcw

null casts to 0 as a number: (+null)is 0. > and < cast null to this value, so when compared to numbers it acts as zero. ==doesn't cast null to a number, so null == 0is false.

null 将 0 作为数字强制转换为 0:(+null)是 0。> 和 < 将null 强制转换为该值,因此与数字相比,它充当零。==不会将 null 转换为数字,因此null == 0为 false。