最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

在javascript中,null>=0 為真,null==0卻為假,null的值詳解

 更新時間:2017年02月22日 08:29:39   投稿:lqh  
這篇文章主要介紹了在javascript中,null>=0 為真,null==0卻為假,null的值詳解的相關(guān)資料,需要的朋友可以參考下

在javascript中,null>=0 為真,null==0卻為假,null的值詳解

1.前言

今天看見朋友們在討論一個問題,說 null 到底和 0 是不是相等的。

聽到這里,自己趕緊去寫個 Demo 試一下。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>MR_LP:3206064928</title>
</head>
<body>

</body>
<script type="text/javascript">
  console.log(null > 0);   // false
  console.log(null < 0);   // false
  console.log(null >= 0);   // true
  console.log(null <= 0);   // true
  console.log(null == 0);   // false
  console.log(null === 0);    // false
</script>
</html>

什么情況?

為什么 console.log(null <= 0); 和 console.log(null >= 0); 這兩條的判斷是 true 呢?

2.查閱資料

如果想明確,這個問題具體是怎么回事,那么我們需要重新來回顧一下我們的 ECMAScript Language Specification (HTML version),翻譯過來就是ECMAScript語言規(guī)范(HTML版本)。

2.1 內(nèi)部相等性運算算法

首先我們來看一下 ES3 關(guān)于 內(nèi)部相等性運算的算法實現(xiàn)。

11.9.3 The Abstract Equality Comparison Algorithm 
The comparison x == y, where x and y are values, produces true or false. Such a comparison is performed as follows: 
1. If Type(x) is different from Type(y), Go to step 14. 
2. If Type(x) is Undefined, return true. 
3. If Type(x) is Null, return true. 
4. If Type(x) is not Number, go to step 11. 
5. If x is NaN, return false. 
6. If y is NaN, return false. 
7. If x is the same number value as y, return true. 
8. If x is +0 and y is -0, return true. 
9. If x is -0 and y is +0, return true. 
10. Return false. 
11. If Type(x) is String, then return true if x and y are exactly the same sequence of characters (same length and same characters in corresponding positions). Otherwise, return false. 
12. If Type(x) is Boolean, return true if x and y are both true or both false. Otherwise, return false. 
13. Return true if x and y refer to the same object or if they refer to objects joined to each other (see 13.1.2). Otherwise, return false. 
14. If x is null and y is undefined, return true. 
15. If x is undefined and y is null, return true. 
16. If Type(x) is Number and Type(y) is String, return the result of the comparison x == ToNumber(y). 
17. If Type(x) is String and Type(y) is Number, return the result of the comparison ToNumber(x)== y. 
18. If Type(x) is Boolean, return the result of the comparison ToNumber(x)== y. 
19. If Type(y) is Boolean, return the result of the comparison x == ToNumber(y). 
20. If Type(x) is either String or Number and Type(y) is Object, return the result of the comparison x == ToPrimitive(y). 
21. If Type(x) is Object and Type(y) is either String or Number, return the result of the comparison ToPrimitive(x)== y. 
22. Return false.

2.2 內(nèi)部關(guān)系運算算法

接下來我們再來看一下 ES3 關(guān)于 內(nèi)部關(guān)系運算的算法實現(xiàn)。

11.8.5 The Abstract Relational Comparison Algorithm 
The comparison x < y, where x and y are values, produces true, false, or undefined (which indicates that at least one operand is NaN). Such a comparison is performed as follows: 
1. Call ToPrimitive(x, hint Number). 
2. Call ToPrimitive(y, hint Number). 
3. If Type(Result(1)) is String and Type(Result(2)) is String, go to step 16. (Note that this step differs from step 7 in the algorithm for the addition operator **+ 
* in using *and instead of or.) 
4. Call ToNumber(Result(1)). 
5. Call ToNumber(Result(2)). 
6. If Result(4) is NaN, return undefined. 
7. If Result(5) is NaN, return undefined. 
8. If Result(4) and Result(5) are the same number value, return false. 
9. If Result(4) is +0 and Result(5) is -0, return false. 
10. If Result(4) is -0 and Result(5) is +0, return false. 
11. If Result(4) is +∞, return false. 
12. If Result(5) is +∞, return true. 
13. If Result(5) is -∞, return false. 
14. If Result(4) is -∞, return true. 
15. If the mathematical value of Result(4) is less than the mathematical value of Result(5) — note that these mathematical values are both finite and not both zero — return true. Otherwise, return false. 
16. If Result(2) is a prefix of Result(1), return false. (A string value p is a prefix of string value q if q can be the result of concatenating p and some other string*r*. Note that any string is a prefix of itself, because r may be the empty string.) 
17. If Result(1) is a prefix of Result(2), return true. 
18. Let k be the smallest nonnegative integer such that the character at position k within Result(1) is different from the character at position k within Result(2). (There must be such a k, for neither string is a prefix of the other.) 
19. Let m be the integer that is the code point value for the character at position k within Result(1). 
20. Let n be the integer that is the code point value for the character at position k within Result(2). 
21. If m < n, return true. Otherwise, return false.

2.3 ES3 的 運算符

2.3.1 ES3 的 “>” 運算符:

The Greater-than Operator ( > ) 
The production RelationalExpression : 
RelationalExpression > ShiftExpression is evaluated as follows: 
1. Evaluate RelationalExpression. 
2. Call GetValue(Result(1)). 
3. Evaluate ShiftExpression. 
4. Call GetValue(Result(3)). 
5. Perform the comparison Result(4) < Result(2). 
6. If Result(5) is undefined, return false. Otherwise, return Result(5).

2.3.2 ES3 的”>=” 運算符:

The Greater-than-or-equal Operator ( >= ) 
The production RelationalExpression : 
RelationalExpression >= ShiftExpression is evaluated as follows: 
1. Evaluate RelationalExpression. 
2. Call GetValue(Result(1)). 
3. Evaluate ShiftExpression. 
4. Call GetValue(Result(3)). 
5. Perform the comparison Result(2) < Result(4). (see 11.8.5). 
6. If Result(5) is true or undefined, return false. Otherwise, return true.

2.3.3 ES3 的 “==” 運算符 :

The Equals Operator ( == ) 
The production EqualityExpression : 
EqualityExpression == RelationalExpression is evaluated as 
follows: 
1. Evaluate EqualityExpression. 
2. Call GetValue(Result(1)). 
3. Evaluate RelationalExpression. 
4. Call GetValue(Result(3)). 
5. Perform the comparison Result(4) == Result(2). (see 11.9.3). 
6. Return Result(5).

3. 根據(jù)資料得出的內(nèi)容

著重看一下,上面特意加粗的地方,我們可以明確下面三件事。

  1. 關(guān)系運算符 和 相等運算符 并不是一個類別的.
  2. 關(guān)系運算符,在設(shè)計上,總是需要運算元嘗試轉(zhuǎn)為一個number . 而相等運算符在設(shè)計上,則沒有這方面的考慮.
  3. 最重要的一點, 不要把 拿 a > b , a == b 的結(jié)果 想當然的去和 a >= b 建立聯(lián)系. 正確的符合最初設(shè)計思想的關(guān)系是 a > b 與 a >= b是一組 . a == b 和其他相等運算符才是一組. 比如 a === b , a != b, a !== b .

那么我們就可以反過來看這個問題了。

null > 0   // null 嘗試轉(zhuǎn)型為number , 則為0 . 所以結(jié)果為 false, 
null >= 0  // null 嘗試轉(zhuǎn)為number ,則為0 , 結(jié)果為 true. 
null == 0  // null在設(shè)計上,在此處不嘗試轉(zhuǎn)型. 所以 結(jié)果為false. 

這里引用一下 Franky大大的話。

a >= b 運算符只是簡單的去對 a < b的結(jié)果取反. 我以為這是一個設(shè)計上的失誤的另一個理由是 undefined,在標準中,被單拎出來.細心的你,也一定發(fā)現(xiàn)了這一點. 對于undefined的設(shè)計,  undefined > 0  , undefined < 0, undefined == 0 的結(jié)果是符合設(shè)計上,邏輯的一致性的. 而null是被遺漏的東西.直到今天早上.我重新翻閱了ES3,5.相關(guān)章節(jié). 才恍然大悟自己沒有從根本上理解到這個問題.

雖然前面的例子,我catch到了BE當初的設(shè)計思想. 但是從全局的角度來看. 從關(guān)系運算符到相等運算符,尤其是相等運算符的設(shè)計上. 真的十分混亂不堪. BE在信中提到,他對 == 的現(xiàn)狀也很無奈. 甚至用愚蠢這個詞來形容自己當初的實現(xiàn)(當然他還提到,當初只是為了在10天內(nèi)設(shè)計出js,并跑過qa的測試用例). 即使如此, 但是他仍然表示 null == 0 這個結(jié)果是他想要的.      

好吧,到了這里,我也有種無力感. 我認為縱觀JavaScript,對關(guān)系運算和相等運算的設(shè)計.除了混亂,我想不出還有什么詞來形容它們更恰當. 這一點從,我們生產(chǎn)環(huán)境代碼中,大量的類型檢查,和防御性代碼的的存在,就可以證明這一點.

同時 Franky大大還舉了另外一個例子。

function case1(a){
  if(a == null){
     ....
  }
} 
 
function case2(a){
  if(a == undefined){
    ...
  }  
}
 
// 上面兩組完全等價, 這就是一種不明確表述.
// 我們永遠不知道代碼編寫者的目的到底是同時匹配null 和 undefined還是只匹配其中某一個
 
 
function case3(a){
  if(a === null || a === undefined){
    ...
  }
}
 
// case3 才是最好的表述. 我們明確知道代碼編寫者的意圖. 
// 即使很多人可能認為這個代碼很愚蠢. 但我堅定的認為這才是好代碼.

最后, 不得不提到,我發(fā)出null >= 0 這封信后, Andrea Giammarchi 表示了對我之前看法的支持,他同我最初的看法一樣,認為 null >= 0 的結(jié)果應該為 false . 并建議在 ES7 中的嚴格模式中,修改這個結(jié)果. 雖然同樣遭到 David Bruant 的反對.  好吧為他和我的這個錯誤看法,默哀一分鐘…

4.后記

所以寫代碼,寫規(guī)范,都應該明確表述. 即使表述的很羅嗦,但不會引起歧義或懷疑. 這才是一份好的標準.文檔,代碼. 而避免歧義,和各種混亂不堪的規(guī)則,是一門語言最應遵守的設(shè)計原則.

最后也希望大家在日常的開發(fā)中,能夠少遇坑。

相關(guān)文章

  • 小程序跳轉(zhuǎn)到的H5頁面再跳轉(zhuǎn)回跳小程序的方法

    小程序跳轉(zhuǎn)到的H5頁面再跳轉(zhuǎn)回跳小程序的方法

    這篇文章主要介紹了小程序跳轉(zhuǎn)到的H5頁面再跳轉(zhuǎn)回跳小程序的方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-03-03
  • JavaScript中return返回多個值的三個方法實現(xiàn)

    JavaScript中return返回多個值的三個方法實現(xiàn)

    本文主要介紹了JavaScript中return返回多個值的三個方法實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-08-08
  • javascript模擬C#格式化字符串

    javascript模擬C#格式化字符串

    學習C#的朋友都知道format()這個方法,本文給大家介紹在javascript中如何實現(xiàn)此操作,js模擬C#字符串格式化操作,需要的盆友一起學習吧
    2015-08-08
  • IE6兼容透明背景圖片及解決方案

    IE6兼容透明背景圖片及解決方案

    這篇文章給大家介紹IE6兼容透明背景圖片以及在IE6中的透明圖片不是透明顯示的解決方案,有需要的朋友可以參考下
    2015-08-08
  • Javascript 是你的高階函數(shù)(高級應用)

    Javascript 是你的高階函數(shù)(高級應用)

    這篇文章主要介紹了Javascript 是你的高階函數(shù) ,需要的朋友可以參考下
    2015-06-06
  • 10道典型的JavaScript面試題

    10道典型的JavaScript面試題

    本文主要介紹了10道典型的JavaScript面試題。具有很好的參考價值。下面跟著小編一起來看下吧
    2017-03-03
  • JS獲取url參數(shù)、主域名的方法實例分析

    JS獲取url參數(shù)、主域名的方法實例分析

    這篇文章主要介紹了JS獲取url參數(shù)、主域名的方法,結(jié)合實例形式分析了javascript針對主機域名、端口、路徑名、URL參數(shù)等的相關(guān)操作技巧,需要的朋友可以參考下
    2016-08-08
  • webpack打包優(yōu)化的幾個方法總結(jié)

    webpack打包優(yōu)化的幾個方法總結(jié)

    這篇文章主要介紹了webpack打包優(yōu)化的幾個方法總結(jié),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-02-02
  • Dropify.js圖片寬高自適應的方法

    Dropify.js圖片寬高自適應的方法

    本篇文章主要介紹了Dropify.js圖片寬高自適應的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-11-11
  • 使用javascript做的一個隨機點名程序

    使用javascript做的一個隨機點名程序

    這篇文章主要介紹了使用javascript做的一個隨機點名程序,經(jīng)測試,效果相當不錯,需要的朋友可以參考下
    2014-02-02

最新評論

石泉县| 岳西县| 固镇县| 胶州市| 博客| 富裕县| 宜州市| 龙川县| 万源市| 西华县| 确山县| 全椒县| 隆化县| 商南县| 弥勒县| 祁阳县| 兖州市| 龙海市| 浦东新区| 岳西县| 九龙城区| 达州市| 三门县| 汾阳市| 东源县| 呼伦贝尔市| 贵阳市| 黄山市| 广河县| 田阳县| 牙克石市| 仁化县| 麻阳| 禹州市| 景东| 九江市| 搜索| 新建县| 天全县| 桓仁| 方正县|