現代 JavaScript 教程 — 學會不一樣類型值的比較

值的比較

咱們知道,在數學中有不少用於比較大小的運算符:javascript

  • 大於 / 小於:a > ba < b
  • 大於等於 / 小於等於:a >= ba <= b
  • 檢測兩個值的相等:a == b(注意表達式中是兩個等號 =,若寫爲單個等號 a = b 則表示賦值)。
  • 檢測兩個值不相等,在數學中使用 符號,而在 JavaScript 中則經過在賦值符號前加歎號表示:a != b

比較結果爲 Boolean 類型

和其餘操做符同樣,比較操做符也會有返回值,返回值爲布爾值(Boolean)。html

  • true —— 表示「yes(是)」,「correct(正確)」或「the truth(真相)」。
  • false —— 表示「no(否)」,「wrong(錯誤)」或「not the truth(非真相)」。

示例:java

alert( 2 > 1 );  // true(正確)
alert( 2 == 1 ); // false(錯誤)
alert( 2 != 1 ); // true(正確)
複製代碼

和其餘類型的值同樣,比較的結果能夠被賦值給任意變量:react

let result = 5 > 4; // 把比較的結果賦值給 result
alert( result ); // true
複製代碼

字符串比較

在比較字符串的大小時,JavaScript 會使用「字典(dictionary)」或「詞典(lexicographical)」順序進行斷定。算法

換言之,字符串是按字符(母)逐個進行比較的。微信

例如:app

alert( 'Z' > 'A' ); // true
alert( 'Glow' > 'Glee' ); // true
alert( 'Bee' > 'Be' ); // true
複製代碼

字符串的比較算法很是簡單:學習

  1. 首先比較兩個字符串的首位字符大小。
  2. 若是一方字符較大(或較小),則該字符串大於(或小於)另外一個字符串。算法結束。
  3. 不然,若是兩個字符串的首位字符相等,則繼續取出兩個字符串各自的後一位字符進行比較。
  4. 重複上述步驟進行比較,直到比較完成某字符串的全部字符爲止。
  5. 若是兩個字符串的字符同時用完,那麼則斷定它們相等,不然未結束(還有未比較的字符)的字符串更大。

在上面的例子中,'Z' > 'A' 在算法的第 1 步就獲得了返回結果,而字符串 GlowGlee 則繼續逐個字符比較:ui

  1. GG 相等。
  2. ll 相等。
  3. oe 大,算法中止,第一個字符串大於第二個。

非真正的字典順序,而是 Unicode 編碼順序

在上面的算法中,比較大小的邏輯與字典或電話簿中的排序很像,但也不徹底相同。編碼

好比說,字符串比較對字母大小寫是敏感的。大寫的 "A" 並不等於小寫的 "a"。哪個更大呢?實際上小寫的 "a" 更大。這是由於在 JavaScript 使用的內部編碼表中(Unicode),小寫字母的字符索引值更大。咱們會在 info:string 這章討論更多關於字符串的細節。

不一樣類型間的比較

當對不一樣類型的值進行比較時,JavaScript 會首先將其轉化爲數字(number)再斷定大小。

例如:

alert( '2' > 1 ); // true,字符串 '2' 會被轉化爲數字 2
alert( '01' == 1 ); // true,字符串 '01' 會被轉化爲數字 1
複製代碼

對於布爾類型值,true 會被轉化爲 1false 轉化爲 0

例如:

alert( true == 1 ); // true
alert( false == 0 ); // true
複製代碼

一個有趣的現象

有時候,如下兩種狀況會同時發生:

  • 若直接比較兩個值,其結果是相等的。
  • 若把兩個值轉爲布爾值,它們可能得出徹底相反的結果,即一個是 true,一個是 false

例如:

let a = 0;
alert( Boolean(a) ); // false

let b = "0";
alert( Boolean(b) ); // true

alert(a == b); // true!
複製代碼

對於 JavaScript 而言,這種現象其實挺正常的。由於 JavaScript 會把待比較的值轉化爲數字後再作比較(所以 "0" 變成了 0)。若只是將一個變量轉化爲 Boolean 值,則會使用其餘的類型轉換規則。

嚴格相等

普通的相等性檢查 == 存在一個問題,它不能區分出 0false

alert( 0 == false ); // true
複製代碼

也一樣沒法區分空字符串和 false

alert( '' == false ); // true
複製代碼

這是由於在比較不一樣類型的值時,處於相等判斷符號 == 兩側的值會先被轉化爲數字。空字符串和 false 也是如此,轉化後它們都爲數字 0。

若是咱們須要區分 0false,該怎麼辦?

嚴格相等操做符 === 在進行比較時不會作任何的類型轉換。

換句話說,若是 ab 屬於不一樣的數據類型,那麼 a === b 不會作任何的類型轉換而馬上返回 false

讓咱們試試:

alert( 0 === false ); // false,由於被比較值的數據類型不一樣
複製代碼

一樣的,與「不相等」符號 != 相似,「嚴格不相等」表示爲 !==

嚴格相等的操做符雖然寫起來稍微長一些,可是它可以很清楚地顯示代碼意圖,下降你犯錯的可能性。

對 null 和 undefined 進行比較

當使用 nullundefined 與其餘值進行比較時,其返回結果經常出乎你的意料。

當使用嚴格相等 === 比較兩者時:它們不相等,由於它們屬於不一樣的類型。

alert( null === undefined ); // false
複製代碼

當使用非嚴格相等 == 比較兩者時:JavaScript 存在一個特殊的規則,會斷定它們相等。他們倆就像「一對戀人」,僅僅等於對方而不等於其餘任何的值(只在非嚴格相等下成立)。

alert( null == undefined ); // true
複製代碼

當使用數學式或其餘比較方法 < > <= >= 時:null/undefined 會被轉化爲數字。null 被轉化爲 0undefined 被轉化爲 NaN

下面讓咱們看看,這些規則會帶來什麼有趣的現象。同時更重要的是,咱們須要從中學會如何遠離這些特性帶來的「陷阱」。

奇怪的結果:null vs 0

經過比較 null 和 0 可得:

alert( null > 0 );  // (1) false
alert( null == 0 ); // (2) false
alert( null >= 0 ); // (3) true
複製代碼

是的,上面的結果徹底打破了你對數學的認識。在最後一行代碼顯示「null 大於等於 0」的狀況下,前兩行代碼中必定會有一個是正確的,然而事實代表它們的結果都是 false。

爲何會出現這種反常結果,這是由於相等性檢測 == 和普通比較符 > < >= <= 的代碼邏輯是相互獨立的。進行值的比較時,null 會被轉化爲數字,所以它被轉化爲了 0。這就是爲何(3)中 null >= 0 返回值是 true,(1)中 null > 0 返回值是 false。

另外一方面,undefinednull 在相等性檢測 == 中不會進行任何的類型轉換,它們有本身獨立的比較規則,因此除了它們之間互等外,不會等於任何其餘的值。這就解釋了爲何(2)中 null == 0 會返回 false。

特立獨行的 undefined

undefined 不該該被與其餘值進行比較:

alert( undefined > 0 ); // false (1)
alert( undefined < 0 ); // false (2)
alert( undefined == 0 ); // false (3)
複製代碼

爲什麼它看起來如此厭惡 0?返回值都是 false!

緣由以下:

  • (1)(2) 都返回 false 是由於 undefined 在比較中被轉換爲了 NaN,而 NaN 是一個特殊的數值型值,它與任何值進行比較都會返回 false
  • (3) 返回 false 是由於這是一個相等性檢測,而 undefined 只與 null 相等,不會與其餘值相等。

規避錯誤

咱們爲什麼要研究上述示例?咱們須要時刻記得這些古怪的規則嗎?不,其實不須要。雖然隨着代碼寫得愈來愈多,咱們對這些規則也都會爛熟於胸,可是咱們須要更爲可靠的方法來避免潛在的問題:

除了嚴格相等 === 外,其餘凡有 undefined/null 參與的比較,咱們都須要額外當心。

除非你很是清楚本身在作什麼,不然永遠不要使用 >= > < <= 去比較一個可能爲 null/undefined 的變量。對於取值多是 null/undefined 的變量,請按須要分別檢查它的取值狀況。

總結

  • 比較運算符始終返回布爾值。
  • 字符串的比較,會按照「詞典」順序逐字符地比較大小。
  • 當對不一樣類型的值進行比較時,它們會先被轉化爲數字(不包括嚴格相等檢測)再進行比較。
  • 在非嚴格相等 == 下,nullundefined 相等且各自不等於任何其餘的值。
  • 在使用 >< 進行比較時,須要注意變量可能爲 null/undefined 的狀況。比較好的方法是單獨檢查變量是否等於 null/undefined

做業題

先本身作題目再看答案。

值的比較

重要程度:⭐️⭐️⭐️⭐️⭐️

如下表達式的執行結果是?

5 > 4
"apple" > "pineapple"
"2" > "12"
undefined == null
undefined === null
null == "\n0\n"
null === +"\n0\n"
複製代碼

答案

5 > 4true
"apple" > "pineapple"false
"2" > "12"true
undefined == nulltrue
undefined === nullfalse
null == "\n0\n"false
null === +"\n0\n"false
複製代碼

結果的緣由:

  1. 數字間比較大小,顯然得 true。
  2. 按詞典順序比較,得 false。
  3. 與第 2 題同理,首位字符 "2" 大於 "1"
  4. null 只與 undefined 互等。
  5. 嚴格相等模式下,類型不一樣得 false。
  6. 與第 4 題同理,null 只與 undefined 相等。
  7. 不一樣類型嚴格不相等。

現代 JavaScript 教程:開源的現代 JavaScript 從入門到進階的優質教程。React 官方文檔推薦,與 MDN 並列的 JavaScript 學習教程

在線免費閱讀:zh.javascript.info


掃描下方二維碼,關注微信公衆號「技術漫談」,訂閱更多精彩內容。

相關文章
相關標籤/搜索