咱們知道,在數學中有不少用於比較大小的運算符:javascript
a > b
,a < b
。a >= b
,a <= b
。a == b
(注意表達式中是兩個等號 =
,若寫爲單個等號 a = b
則表示賦值)。≠
符號,而在 JavaScript 中則經過在賦值符號前加歎號表示:a != b
。和其餘操做符同樣,比較操做符也會有返回值,返回值爲布爾值(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
複製代碼
字符串的比較算法很是簡單:學習
在上面的例子中,'Z' > 'A'
在算法的第 1 步就獲得了返回結果,而字符串 Glow
與 Glee
則繼續逐個字符比較:ui
G
和 G
相等。l
和 l
相等。o
比 e
大,算法中止,第一個字符串大於第二個。非真正的字典順序,而是 Unicode 編碼順序
在上面的算法中,比較大小的邏輯與字典或電話簿中的排序很像,但也不徹底相同。編碼
好比說,字符串比較對字母大小寫是敏感的。大寫的
"A"
並不等於小寫的"a"
。哪個更大呢?實際上小寫的"a"
更大。這是由於在 JavaScript 使用的內部編碼表中(Unicode),小寫字母的字符索引值更大。咱們會在 info:string 這章討論更多關於字符串的細節。
當對不一樣類型的值進行比較時,JavaScript 會首先將其轉化爲數字(number)再斷定大小。
例如:
alert( '2' > 1 ); // true,字符串 '2' 會被轉化爲數字 2
alert( '01' == 1 ); // true,字符串 '01' 會被轉化爲數字 1
複製代碼
對於布爾類型值,true
會被轉化爲 1
、false
轉化爲 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
值,則會使用其餘的類型轉換規則。
普通的相等性檢查 ==
存在一個問題,它不能區分出 0
和 false
:
alert( 0 == false ); // true
複製代碼
也一樣沒法區分空字符串和 false
:
alert( '' == false ); // true
複製代碼
這是由於在比較不一樣類型的值時,處於相等判斷符號 ==
兩側的值會先被轉化爲數字。空字符串和 false
也是如此,轉化後它們都爲數字 0。
若是咱們須要區分 0
和 false
,該怎麼辦?
嚴格相等操做符 ===
在進行比較時不會作任何的類型轉換。
換句話說,若是 a
和 b
屬於不一樣的數據類型,那麼 a === b
不會作任何的類型轉換而馬上返回 false
。
讓咱們試試:
alert( 0 === false ); // false,由於被比較值的數據類型不一樣
複製代碼
一樣的,與「不相等」符號 !=
相似,「嚴格不相等」表示爲 !==
。
嚴格相等的操做符雖然寫起來稍微長一些,可是它可以很清楚地顯示代碼意圖,下降你犯錯的可能性。
當使用 null
或 undefined
與其餘值進行比較時,其返回結果經常出乎你的意料。
當使用嚴格相等 ===
比較兩者時:它們不相等,由於它們屬於不一樣的類型。
alert( null === undefined ); // false
複製代碼
當使用非嚴格相等 ==
比較兩者時:JavaScript 存在一個特殊的規則,會斷定它們相等。他們倆就像「一對戀人」,僅僅等於對方而不等於其餘任何的值(只在非嚴格相等下成立)。
alert( null == undefined ); // true
複製代碼
當使用數學式或其餘比較方法 < > <= >=
時:null/undefined
會被轉化爲數字。null
被轉化爲 0
,undefined
被轉化爲 NaN
。
下面讓咱們看看,這些規則會帶來什麼有趣的現象。同時更重要的是,咱們須要從中學會如何遠離這些特性帶來的「陷阱」。
經過比較 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。
另外一方面,undefined
和 null
在相等性檢測 ==
中不會進行任何的類型轉換,它們有本身獨立的比較規則,因此除了它們之間互等外,不會等於任何其餘的值。這就解釋了爲何(2)中 null == 0
會返回 false。
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
的變量,請按須要分別檢查它的取值狀況。
==
下,null
和 undefined
相等且各自不等於任何其餘的值。>
或 <
進行比較時,須要注意變量可能爲 null/undefined
的狀況。比較好的方法是單獨檢查變量是否等於 null/undefined
。先本身作題目再看答案。
重要程度:⭐️⭐️⭐️⭐️⭐️
如下表達式的執行結果是?
5 > 4
"apple" > "pineapple"
"2" > "12"
undefined == null
undefined === null
null == "\n0\n"
null === +"\n0\n"
複製代碼
5 > 4 → true
"apple" > "pineapple" → false
"2" > "12" → true
undefined == null → true
undefined === null → false
null == "\n0\n" → false
null === +"\n0\n" → false
複製代碼
結果的緣由:
"2"
大於 "1"
。null
只與 undefined
互等。null
只與 undefined
相等。現代 JavaScript 教程:開源的現代 JavaScript 從入門到進階的優質教程。React 官方文檔推薦,與 MDN 並列的 JavaScript 學習教程。
在線免費閱讀:zh.javascript.info
掃描下方二維碼,關注微信公衆號「技術漫談」,訂閱更多精彩內容。