null >=0 ? true:false

做者:Abinav Seelan 原文連接:blog.campvanilla.com/javascript-…javascript


在掘金前端羣裏(添加掘金醬:juejinjiang 入羣)問了你們一個問題:html

null > 0false,null == 0false,爲何null>=0true前端

有說 == 不會嘗試轉型,因此 null == 0成立。但我記得不轉型的是===啊。
也有說轉換爲布爾值都爲假,那'' == 0?
還有位羣友給出了Number(null)==0的寫法,讓表達式結果爲 true
可是你們都沒有正面回答問題。java

打開你的瀏覽器,按下f12,在 console 中輸入算法

null > 0;
null == 0;
null >= 0;複製代碼

看看結果是什麼?
null >0 // false
null == 0// false
null >= 0 // true
神奇嗎?一個值既不大於0,也不等於0,但它竟然大於或等於0
必定是個人打開方式有問題,換個瀏覽器試試!
算了,仍是查查 ECMAScript 標準吧。瀏覽器

抽象關係比較算法

先看看bash

null > 0// false複製代碼

根據標準,> <操做符利用抽象關係比較算法判斷表達式爲true或者false優化

  1. 調用 ToPrimitive(X, hint Number)
  2. 調用 ToPrimitive(y, hint Number)
  3. 若是 Type(Result(1)) 是字符串且 Type(Result(2) 是字符串,跳轉到步驟16。
  4. 調用ToNumber(Result(1))
  5. 調用ToNumber(Result(2))
  6. 若是Result(4)是 NaN, 返回 undefined
  7. 若是Result(5)是 NaN, 返回undefined
  8. 若是Result(4)Result(5)是一樣的數字,返回false
  9. 若是Result(4)+0並且Result(5)-0,返回false
  10. 若是Result(4)-0而且Result(5)+0,返回false
  11. 若是Result(4)+∞,返回false
  12. 若是Result(5)+∞,返回true
  13. 若是Result(5)-∞,返回false
  14. 若是Result(5)-∞,返回true
  15. 若是Result(4)數學意義上的值小於Result數學意義上的值——注意這些值都是有窮的且不都爲0——返回true。不然,返回false
  16. 若是Result(2)Result(1)的前綴,返回false(若是字符串 q 能夠由 字符串 p 後跟另外一個字符串 r 鏈接組成,那麼字符串 p 就是字符串 q 的前綴。注意任何一個字符串都是其自己的前綴,由於字符串 r 能夠是空字符串)。
  17. 若是Result(1)Result(2)的前綴,返回true
  18. 讓 k 是最小的非負整數,這樣Result(1)在 k 位置的字符和 Result(2)在 k 位置的字符會不同。(由於兩個字符串都不是另外一個字符串的前綴,因此必定存在這個 k)
  19. 讓 m 是 Result(1)中 k 位置字符的編碼值。
  20. 讓 n 是 Result(2)中 k 位置字符的編碼值。
    21.若是 m<n ,返回true。不然,返回false

null>0在整個算法中過一遍。
步驟一與步驟二null0上調用ToPrimitive()分別將這兩個值轉換爲原始類型(好比NumberString)。ToPrimitive的結果以下表:編碼

Input type Result
Undefined 不轉換
Null 不轉換
Boolean 不轉換
Number 不轉換
String 不轉換
Object 轉換爲對象的默認值。對象的默認值經過調用內部的[[DefaultValue]]方法得到,忽略 hint 參數。

根據上表,null0都沒有轉換。spa

因此步驟三對咱們就不適用了,跳過步驟三。步驟四與步驟五須要將左右值均轉換爲Number類型。Number轉換規則以下:

Input Type Result
Undefined NaN
Null +0
Number 不轉換
Boolean true 轉爲1 ,false 轉爲 +0
... ...

(StringObject 的轉換省掉了,由於暫時用不上。若是你好奇能夠看這個🙃)

null轉換爲+00仍是0。兩個值都不是NaN,因此步驟六與步驟七能夠跳過。步驟八要注意下,+0等於0,因此算法返回false。因此,

null > 0;//false
 and
null < 0;//alse false複製代碼

抽象相等比較算法

如今再來看看,
null == 0//false
這也很是有趣。

==操做符利用抽象相等比較算法判斷true或者false

  1. 若是 Type(x)Type(y) 不一致,跳轉至步驟十四。
  2. 若是Type(x)undefined, 返回 true
  3. 若是 Type(x)Null,返回 true
  4. 若是 Type(x) 不是數字,跳轉到步驟十一。
  5. 若是 xNaN, 返回 false
  6. 若是 yNaN, 返回 false
  7. 若是 xy 是同一個數,返回 true
  8. 若是 x+0y-0,返回 true
  9. 若是 x-0y+0,返回 true
  10. 返回 false
  11. 若是 Type(x) 是字符串,當 xy 是徹底相同的序列時(長度一致,對應位置的字符也同樣。)返回 true。不然返回 false
  12. 若是 Type(x) 是布爾值,當 xy 都爲 true 或都爲 false 時,語句返回 true,不然返回 false
  13. xy 指向同一個對象或指向的兩個對象是聯合對象(參見 13.1.2)時,返回 true ,不然返回 false
  14. 若是 xnullyundefined,返回 true
  15. 若是 xundefinedynull ,返回 true
  16. 若是 Type(x)NumberType(y) 是字符串,返回 x == [ToNumber](http://interglacial.com/javascript_spec/a-9.html#a-9.3)(y) 的結果。
  17. 若是 Type(x)StringType(y) 是數字,返回 [ToNumber](http://interglacial.com/javascript_spec/a-9.html#a-9.3)(x)==y的結果。
  18. 若是 Type(x) 是布爾值,返回 ToNumber(x) == y的結果。
  19. 若是 Type(y) 是布爾值,返回 x ==ToNumber(y)的結果。
  20. 若是 Type(x) 既不是字符串也不是數字而 Type(y) 是對象,返回 x == ToPrimitive(y) 的結果。
  21. 若是 Type(x) 是對象而 Type(y) 是字符串或數字,返回 ToPrimitive(x) == y
  22. 返回 false

判斷 null0 是否相等,咱們馬上從步驟一跳到步驟十四。由於 Type 不同。並且,由於Type(x) 是 null,因此步驟十四到步驟二十一也不適用。最終,步驟二十二默認返回 false。

因此,
null == 0 ; //false

大於等於操做符(>=)

如今,咱們來看最後一個表達式。
null > 0;// true
這一塊標準徹底把我整蒙了。從宏觀看,>=等價於

若是 null < 0false,那麼 null>=0true

因此,
null >= 0; //true

老實說,這是有道理的。數學上講,若是兩個數字xyx 不小於 y,那麼x 必須大於或等於y

我猜這麼作的目的是爲了優化比較表達式。若是能夠一次比較——比較x小於y 是否成立,用這個結果推出原始表達式的結果。那幹嗎還要去先比較x 是否是大於y,若是不是,再比較x是否是等於y呢。

(若是你對>= 操做符的實際運算步驟感興趣,能夠看這個)

在探索這個問題的過程當中,對這門語言又有了更深的認識。但願這篇文章能夠幫助你。

相關文章
相關標籤/搜索