为什么`null> = 0&& null< = 0`但不是`null == 0`?

时间:2010-05-26 06:19:33

标签: javascript comparison null

我必须编写一个例程,如果变量的值为number,则将变量的值递增1,如果不是,则将变量赋值为0,其中变量最初为null或{{1 }}

第一个实现是undefined,因为我认为任何不是数字都会使算术表达式为false,但是由于v >= 0 ? v += 1 : v = 0被评估为true,所以它是错误的。然后我了解到null >= 0的行为类似于0,以下表达式都被评估为真。

  • null
  • null >= 0 && null <= 0
  • !(null < 0 || null > 0)
  • null + 1 === 1
  • 1 / null === Infinity

当然,Math.pow(42, null) === 1不是0. null被评估为false。这使得看似同义的表达null == 0错误。

为什么(v >= 0 && v <= 0) === (v == 0)喜欢0,虽然它实际上不是0?

5 个答案:

答案 0 :(得分:195)

你真正的问题似乎是:

为什么:

null >= 0; // true

可是:

null == 0; // false

实际发生的是大于或等于运算符>=)执行类型强制(ToPrimitive),带有提示< / em>类型Number,实际上所有关系运算符都有此行为。

null等于运算符==)以特殊方式处理。简而言之,只有强制undefined

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

false'''0'[]等值受数字类型强制约束,所有这些都强制为零。

您可以在The Abstract Equality Comparison AlgorithmThe Abstract Relational Comparison Algorithm中查看此流程的内部详细信息。

摘要:

  • 关系比较:如果两个值都不是String类型,则同时调用ToNumber。这与在前面添加+相同,对于null强制转换为0

  • 平等比较:仅对字符串,数字和布尔值调用ToNumber

答案 1 :(得分:11)

我想扩展这个问题,以进一步提高问题的可见性:

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

这没有任何意义。像人类语言一样,这些东西需要用心学习。

答案 2 :(得分:4)

JavaScript具有严格和类型转换比较

null >= 0;是真的 但 (null==0)||(null>0)是假的

null <= 0;为真,但(null==0)||(null<0)为假

"" >= 0也是如此

对于关系抽象比较(&lt; =,&gt; =),在比较之前,操作数首先转换为基元,然后转换为相同的类型。

typeof null returns "object"

当type为object时,javascript尝试对对象进行字符串化(即null) 采取以下步骤(ECMAScript 2015):

  1. 如果未通过PreferredType,请hint为&#34;默认为&#34;。
  2. 如果PreferredTypehint字符串,则hint为&#34;字符串&#34;。
  3. 否则PreferredTypehint号码,请hint为&#34;号码&#34;。
  4. exoticToPrimGetMethod(input, @@toPrimitive)
  5. ReturnIfAbrupt(exoticToPrim)
  6. 如果exoticToPrim未定义,则为 a)让结果为Call(exoticToPrim, input, «hint») b)ReturnIfAbrupt(result)
    c)如果Type(result)不是对象,则返回结果 d)抛出TypeError异常。
  7. 如果hint为&#34;默认为&#34;,请hint为&#34; number&#34;。
  8. 返回OrdinaryToPrimitive(input,hint)
  9. 提示的允许值为&#34;默认&#34;,&#34;数字&#34;和&#34;字符串&#34;。日期对象在内置ECMAScript对象中是唯一的,因为它们处理&#34;默认&#34;等同于&#34; string&#34;。 所有其他内置ECMAScript对象都会处理&#34;默认&#34;等同于&#34;数字&#34; 。 (ECMAScript 20.3.4.45

    所以我认为null会转换为0。

答案 3 :(得分: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 !

答案 4 :(得分:0)

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

从数学上来说,这很奇怪。最后一个结果指出“ null大于或等于零”,因此在上面的比较之一中,它必须为true,但都为false。

原因是相等检查==和比较> < >= <=的工作方式不同。比较会将null转换为数字,将其视为0。这就是(3)null >= 0true和(1)null > 0false的原因。

另一方面,对==undefined的相等性检查null的定义是,在不进行任何转换的情况下,它们彼此相等,而彼此不相等。这就是为什么(2)null == 0false