为什么`null> = 0 && null <= 0`而不是`null == 0`?
我必须编写一个例程,如果variables的types是number ,则将该variables的值递增1,否则将variables赋值为0,其中variables最初为null或undefined 。
第一个实现是v >= 0 ? v += 1 : v = 0 v >= 0 ? v += 1 : v = 0因为我认为任何不是数字都会使算术expression式为false,但是由于null >= 0的计算结果为true,所以是错误的。 然后我知道null行为如同0,下面的expression式都被评估为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。 这使得看起来似乎重复的expression式(v >= 0 && v <= 0) === (v == 0) false。
为什么是0,尽pipe实际上不是0?
你真正的问题似乎是:
为什么:
null >= 0; // true
但:
null == 0; // false
真正发生的事情是, 大于或等于运算符 ( >= )执行types强制( ToPrimitive ),其中提示types为Number ,实际上所有的关系运算符都有这种行为。
null由Equals运算符 ( == )以特殊方式处理。 简而言之,它只是强迫 undefined :
null == null; // true null == undefined; // true
诸如false , '' , '0'和[]的值受到数字types的强制,所有这些都强制为零。
您可以在“抽象平等比较algorithm”和“抽象关系比较algorithm”中看到此过程的内部细节。
综上所述:
-
关系比较:如果两个值都不是Stringtypes,
ToNumber同时调用ToNumber。 这与在前面添加+相同,即空值为0。 -
平等比较:仅在string,数字和布尔值上调用
ToNumber。
我想扩大这个问题来进一步提高问题的可见性:
null >= 0; //true null <= 0; //true null == 0; //false null > 0; //false null < 0; //false
这是没有意义的。 就像人类语言一样,这些东西需要学习。
JavaScript有严格的和types转换的比较
null >= 0; 是true,但是(null==0)||(null>0)是假的
null <= 0; 是true,但是(null==0)||(null<0)是false
"" >= 0也是如此
对于关系抽象比较(<=,> = =),在比较之前,操作数首先转换为原语,然后转换为相同的types。
typeof null returns "object"
当types是对象javascript试图串化对象(即空)采取以下步骤( ECMAScript 2015 ):
- 如果
PreferredType没有通过,让hint是“默认”。 - 否则,如果
PreferredType是hintstring,让hint是“string”。 - 其他
PreferredType是hint号码,让hint是“数字”。 - 让
exoticToPrim成为GetMethod(input, @@toPrimitive)。 -
ReturnIfAbrupt(exoticToPrim)。 - 如果
exoticToPrim不是未定义的,那么
a)让结果被Call(exoticToPrim, input, «hint»)。
b)ReturnIfAbrupt(result)。
c)如果Type(result)不是Object,则返回结果。
d)抛出一个TypeErrorexception。 - 如果
hint是“默认”,让hint是“数字”。 - 返回
OrdinaryToPrimitive(input,hint)。
提示的允许值是“默认”,“数字”和“string”。 Date对象在内置ECMAScript对象中是唯一的,因为它们将“default”视为等同于“string”。 所有其他内置的ECMAScript对象将“default”视为等同于“number” 。 ( ECMAScript 20.3.4.45 )
所以我认为null转换为0。
我有同样的问题 !!。 目前我唯一的解决办法是分开。
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 !