欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

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

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

1.前言

今天看見(jiàn)朋友們?cè)谟懻撘粋€(gè)問(wèn)題,說(shuō) null 到底和 0 是不是相等的。

聽(tīng)到這里,自己趕緊去寫個(gè) 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.查閱資料

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

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

首先我們來(lái)看一下 ES3 關(guān)于 內(nèi)部相等性運(yùn)算的算法實(shí)現(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)系運(yùn)算算法

接下來(lái)我們?cè)賮?lái)看一下 ES3 關(guān)于 內(nèi)部關(guān)系運(yùn)算的算法實(shí)現(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 的 運(yùn)算符

2.3.1 ES3 的 “>” 運(yùn)算符:

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 的”>=” 運(yùn)算符:

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 的 “==” 運(yùn)算符 :

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

那么我們就可以反過(guò)來(lái)看這個(gè)問(wèn)題了。

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

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

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

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

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

同時(shí) Franky大大還舉了另外一個(gè)例子。

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

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

4.后記

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

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

相關(guān)文章

  • 原生js+canvas實(shí)現(xiàn)驗(yàn)證碼

    原生js+canvas實(shí)現(xiàn)驗(yàn)證碼

    這篇文章主要為大家詳細(xì)介紹了原生js+canvas實(shí)現(xiàn)驗(yàn)證碼,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-11-11
  • JavaScript 正則表達(dá)式詳解

    JavaScript 正則表達(dá)式詳解

    正則表達(dá)式(Regular Expression)是一門簡(jiǎn)單語(yǔ)言的語(yǔ)法規(guī)范,是強(qiáng)大、便捷、高效的文本處理工具,它應(yīng)用在一些方法中,對(duì)字符串中的信息實(shí)現(xiàn)查找、替換和提取操作
    2021-11-11
  • JavaScript之IE的fireEvent方法詳細(xì)解析

    JavaScript之IE的fireEvent方法詳細(xì)解析

    剛開(kāi)始我以為是會(huì)跟平時(shí)使用onclick()一樣,沒(méi)想到最近在寫javascript入門ppt的時(shí)候發(fā)現(xiàn)了,原來(lái)自己太自以為是了!看來(lái)還有很多javascript的細(xì)節(jié)沒(méi)有掌握好啊
    2013-11-11
  • 前端實(shí)現(xiàn)讀取word文件并將其原樣式展示的幾種方案

    前端實(shí)現(xiàn)讀取word文件并將其原樣式展示的幾種方案

    在前端直接讀取并原樣展示W(wǎng)ord文檔是一個(gè)相對(duì)復(fù)雜的任務(wù),因?yàn)閃ord文檔的格式(如.doc或.docx)與Web技術(shù)棧使用的格式(HTML、CSS)不兼容,這篇文章主要給大家介紹了關(guān)于前端實(shí)現(xiàn)讀取word文件并將其原樣式展示的幾種方案,需要的朋友可以參考下
    2024-08-08
  • javascript入門基礎(chǔ)之私有變量

    javascript入門基礎(chǔ)之私有變量

    開(kāi)始接觸這門語(yǔ)言時(shí),可能都會(huì)覺(jué)得這門語(yǔ)言缺少訪問(wèn)控制符(如public、private、protected),從而導(dǎo)致不能定義私有變量和私有方法。但經(jīng)過(guò)進(jìn)一步了解就會(huì)知道javascript同樣可以有私有變量。
    2010-02-02
  • JavaScript實(shí)現(xiàn)復(fù)選框全選或全取消操作

    JavaScript實(shí)現(xiàn)復(fù)選框全選或全取消操作

    這篇文章主要為大家詳細(xì)介紹了JavaScript實(shí)現(xiàn)復(fù)選框全選或全取消操作,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • ie focus bug 解決方法

    ie focus bug 解決方法

    在IE中,新創(chuàng)建的input沒(méi)有如預(yù)期的獲得焦點(diǎn)。
    2009-09-09
  • 微信小程序簡(jiǎn)單的canvas裁剪圖片功能詳解

    微信小程序簡(jiǎn)單的canvas裁剪圖片功能詳解

    這篇文章主要介紹了微信小程序簡(jiǎn)單的canvas裁剪圖片功能詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-07-07
  • 微信小程序復(fù)選框?qū)崿F(xiàn)多選一功能過(guò)程解析

    微信小程序復(fù)選框?qū)崿F(xiàn)多選一功能過(guò)程解析

    這篇文章主要介紹了微信小程序復(fù)選框?qū)崿F(xiàn)多選一功能過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-02-02
  • CSS+Table圖文混排中實(shí)現(xiàn)文本自適應(yīng)圖片寬度(超簡(jiǎn)單+跨所有瀏覽器)

    CSS+Table圖文混排中實(shí)現(xiàn)文本自適應(yīng)圖片寬度(超簡(jiǎn)單+跨所有瀏覽器)

    最近在為學(xué)樂(lè)網(wǎng)開(kāi)發(fā)圖片顯示功能時(shí)遇到一個(gè)問(wèn)題:在一個(gè)table中有兩行,上邊顯示圖片(大小隨機(jī)),下邊顯示對(duì)圖片的相關(guān)說(shuō)明(文字長(zhǎng)度隨機(jī))
    2009-02-02

最新評(píng)論