为什么`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
是hint
string,让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 !