为什么‘ null > = 0 & & null < = 0’而不是‘ null = = 0’?

我必须编写一个例程,如果一个变量的类型是 number,那么它的值就递增1,如果不是,则赋0给该变量,其中该变量最初是 nullundefined

第一个实现是 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被计算为 false。这使得看似重复的表达式 (v >= 0 && v <= 0) === (v == 0)为 false。

为什么 null像0,尽管它实际上不是0?

70269 次浏览

你真正的问题似乎是:

原因:

null >= 0; // true

但是:

null == 0; // false

实际发生的情况是,大于等于运算符(>=)执行类型强制(ToPrimitive) ,提示类型为 Number,实际上所有的关系操作符都有这种行为。

null等于运算符(==)以一种特殊的方式处理。简而言之,它只有 胁迫undefined:

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

诸如 false'''0'[]之类的值受到数字类型强制,它们都强制为零。

您可以在 抽象等式比较算法抽象关系比较算法中看到这个过程的内部细节。

总结:

  • 关系比较: 如果两个值都不是 String 类型,则对两个值都调用 ToNumber。这与在前面添加一个 +是相同的,这对于空胁迫来说是 0

  • 相等比较: 只对字符串、数字和布尔值调用 ToNumber

我想扩大这个问题的范围,以进一步提高这个问题的可见度:

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

这根本说不通,就像人类的语言一样,这些东西需要用心学习。

我也有同样的问题。 目前我唯一的解决办法就是。

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 !

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

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

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

"" >= 0也是正确的

对于关系抽象比较(< = ,> =) ,操作数首先转换为基元,然后在比较之前转换为同一类型。

typeof null returns "object"

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

  1. 如果没有传递 PreferredType,那么将 hint设为“ default”。
  2. 否则,如果 PreferredTypehint字符串,那么让 hint是“ String”。
  3. 否则 PreferredTypehint数字,让 hint是“数字”。
  4. exoticToPrimGetMethod(input, @@toPrimitive)
  5. ReturnIfAbrupt(exoticToPrim).
  6. 如果 exoticToPrim不是未定义的,则
    A)让结果为 Call(exoticToPrim, input, «hint»)
    B) ReturnIfAbrupt(result).
    C)如果 Type(result)不是 Object,则返回结果。
    D)抛出 TypeError 异常。
  7. 如果 hint是“默认值”,那么让 hint是“数字”。
  8. 返回 OrdinaryToPrimitive(input,hint)

允许的提示值是“ default”、“ number”和“ string”。Date 对象在内置 ECMAScript 对象中是唯一的,因为它们将“ default”等效为“ string”。 所有其他内置的 ECMAScript 对象都将“ default”等同于“ number” (ECMAScript 20.3.4.45)

所以我认为 null转换为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

另一方面,undefinednull的相等性检查 ==的定义是这样的,在没有任何转换的情况下,它们彼此相等,不等于任何其他值。这就是为什么(2) null == 0false

看起来检查 x >= 0的方法是 !(x < 0),这样反应就有意义了。