为什么`null >= 0 && null <= 0` 但不是 `null == 0`?
我必须编写一个例程,如果变量的类型是 number
,则该变量的值加 1;如果不是,则将 0 分配给变量,其中变量最初为 null
或未定义
。
第一个实现是 v >= 0 ? v += 1 : v = 0
因为我认为任何不是数字的东西都会使算术表达式为 false,但这是错误的,因为 null >= 0
被评估为 true。然后我了解到 null
的行为类似于 0,并且以下表达式全部计算为 true。
-
null >= 0 && null <= 0
-
!(null < 0 || null > 0)
-
null + 1 === 1
-
1 / null = == Infinity
-
Math.pow(42, null) === 1
当然,null
不是 0。 null == 0
code> 被评估为 false。这使得看似同义反复的表达式 (v >= 0 && v <= 0) === (v == 0)
为假。
为什么 null
像 0,尽管它实际上不是 0?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
JavaScript 具有严格比较和类型转换比较
null >= 0;
为 true但
(null==0)||(null>0)
为 falsenull <= 0;
为 true,但(null==0)||( null<0)
为 false"" >= 0
也为 true对于关系抽象比较(<= 、>=),操作数首先转换为基元,然后转换为相同类型,比较之前。
typeof null returns "object"
当 type 是 object 时,javascript 尝试将对象字符串化(即 null)
采取以下步骤 (ECMAScript 2015):
hint
为“默认”。PreferredType
是hint
字符串,则让hint
为“string”。PreferredType
是hint
Number,让hint
为“number”。exoticToPrim
为GetMethod(input, @@toPrimitive)
。ReturnIfAbrupt(exoticToPrim)
。exoticToPrim
不是未定义的,则a) 令结果为
Call(exoticToPrim, input, «hint»)
。b)
ReturnIfAbrupt(结果)
.c) 如果
Type(result)
不是Object,则返回结果。d) 抛出 TypeError 异常。
hint
为“default”,则让hint
为“number”。提示的允许值为“默认”、“数字”和“字符串”。日期对象在内置 ECMAScript 对象中是独一无二的,因为它们将“默认”视为等同于“字符串”。
所有其他内置 ECMAScript 对象将“default”视为等同于“number”。 (ECMAScript 20.3.4.45)
所以我认为
null
会转换为 0。JavaScript has both strict and type–converting comparisons
null >= 0;
is truebut
(null==0)||(null>0)
is falsenull <= 0;
is true but(null==0)||(null<0)
is false"" >= 0
is also trueFor relational abstract comparisons (<= , >=), the operands are first converted to primitives, then to the same type, before comparison.
typeof null returns "object"
When type is object javascript tries to stringify the object (i.e null)
the following steps are taken (ECMAScript 2015):
PreferredType
was not passed, lethint
be "default".PreferredType
ishint
String, lethint
be "string".PreferredType
ishint
Number, lethint
be "number".exoticToPrim
beGetMethod(input, @@toPrimitive)
.ReturnIfAbrupt(exoticToPrim)
.exoticToPrim
is not undefined, thena) Let result be
Call(exoticToPrim, input, «hint»)
.b)
ReturnIfAbrupt(result)
.c) If
Type(result)
is not Object, return result.d) Throw a TypeError exception.
hint
is "default", lethint
be "number".OrdinaryToPrimitive(input,hint)
.The allowed values for hint are "default", "number", and "string". Date objects, are unique among built-in ECMAScript object in that they treat "default" as being equivalent to "string".
All other built-in ECMAScript objects treat "default" as being equivalent to "number". (ECMAScript 20.3.4.45)
So I think
null
converts to 0.我有同样的问题!
目前我唯一的解决办法就是分开。
I had the same problem !!.
Currently my only solution is to separate.
看起来检查
x >= 0
的方法是!(x < 0)
这样响应才有意义。It looks like the way to check
x >= 0
is!(x < 0)
In that way make sense the response.您真正的问题似乎是:
为什么:
但是:
真正发生的是大于或等于运算符(
>=
)执行类型强制转换(< a href="http://www.ecma-international.org/ecma-262/5.1/#sec-9.1" rel="nofollow noreferrer">ToPrimitive
),带有hint类型的Number
,实际上所有关系运算符都有这种行为。null
由等于运算符 (==
) 以特殊方式处理。简而言之,它仅强制为未定义
:值
false
、'0'
和[ ]
受到数字强制为零。当修剪空白后结果为空字符串 (""
) 时,字符串强制为零。您可以在 摘要中查看此过程的内部细节相等比较算法和抽象关系比较算法。
总结:
ToNumber
。这与在前面添加+
相同,对于 null 强制转换为0
。这也解释了如何对 Date 对象进行数值比较。
对于
null >= 0
,如ToPrimitive(null,hint: Number)
结果null
。对于 EcmaScript 5.1 的“抽象关系比较算法”,这发生在步骤 3。EcmaScript
2025, 7.2.12 IsLessThan ( x, y, LeftFirst ),步骤 4 效果相同。 (请参阅:https://tc39.es/ecma262/#sec-islessthan)
ToNumber
。7.1.4 ToNumber(参数)
抽象操作 ToNumber 采用参数参数(ECMAScript 语言值)并返回包含 Number 的正常完成或抛出完成。它将参数转换为 Number 类型的值。调用时它执行以下步骤:
Your real question seem to be:
Why:
But:
What really happens is that the Greater-than-or-equal Operator (
>=
), performs type coercion (ToPrimitive
), with a hint type ofNumber
, actually all the relational operators have this behavior.null
is treated in a special way by the Equals Operator (==
). In a brief, it only coerces toundefined
:Values
false
,'0'
, and[]
are subject to numeric coercion to zero. Strings coerce to zero when, after trimming whitespace, the result is the empty string (""
).You can see the inner details of this process in the The Abstract Equality Comparison Algorithm and The Abstract Relational Comparison Algorithm.
In Summary:
ToNumber
is called on both. This is the same as adding a+
in front, which for null coerces to0
.This also explains how Date objects can be compared numerically.
As for
null >= 0
, asToPrimitive(null, hint: Number)
resultsnull
.For the "The Abstract Relational Comparison Algorithm" of EcmaScript 5.1, this occurs in step 3.
EcmaScript 2025, 7.2.12 IsLessThan ( x, y, LeftFirst ), step 4 the same effect. (see: https://tc39.es/ecma262/#sec-islessthan)
ToNumber
on Strings, Numbers, and Booleans.7.1.4 ToNumber ( argument )
The abstract operation ToNumber takes argument argument (an ECMAScript language value) and returns either a normal completion containing a Number or a throw completion. It converts argument to a value of type Number. It performs the following steps when called:
我想扩展这个问题以进一步提高问题的可见性:
这毫无意义。就像人类语言一样,这些东西需要死记硬背。
I'd like to extend the question to further improve visibility of the problem:
It just makes no sense. Like human languages, these things need be learned by heart.
从数学上来说,这很奇怪。最后一个结果表明“null 大于或等于零”,因此在上面的比较之一中它必须为 true,但它们都是 false。
原因是相等检查
==
和比较> 。 < >= <=
的工作方式不同。比较将 null 转换为数字,将其视为0
。这就是为什么 (3)null >= 0
为true
而 (1)null >= 0
的原因。 0 是假
。另一方面,对
undefined
和null
的相等性检查==
被定义为,无需任何转换,它们就彼此相等并且不存在。不等于其他任何东西。这就是为什么 (2)null == 0
是false
。Mathematically, that’s strange. The last result states that "null is greater than or equal to zero", so in one of the comparisons above it must be true, but they are both false.
The reason is that an equality check
==
and comparisons> < >= <=
work differently. Comparisons convert null to a number, treating it as0
. That’s why (3)null >= 0
istrue
and (1)null > 0
isfalse
.On the other hand, the equality check
==
forundefined
andnull
is defined such that, without any conversions, they equal each other and don’t equal anything else. That’s why (2)null == 0
isfalse
.