W3Cschool
恭喜您成為首批注冊用戶
獲得88經驗值獎勵
我們知道,在數學中有很多用于比較大小的運算符。
在 JavaScript 中,它們的編寫方式如下:
a > b
?,?a < b
?。a >= b
?,?a <= b
?。a == b
?,請注意雙等號 ?==
? 表示相等性檢查,而單等號 ?a = b
? 表示賦值。≠
?,但在 JavaScript 中寫成 ?a != b
?。在本文中,我們將進一步了解不同類型的比較,JavaScript 是如何進行比較的,包括一些重要的特殊性。
在文末給出了一些秘訣,幫助你避免 “JavaScript 陷阱”相關的問題。
所有比較運算符均返回布爾值:
true
?—— 表示“yes(是)”,“correct(正確)”或“the truth(真)”。false
?—— 表示“no(否)”,“wrong(錯誤)”或“not the truth(非真)”。示例:
alert( 2 > 1 ); // true(正確)
alert( 2 == 1 ); // false(錯誤)
alert( 2 != 1 ); // true(正確)
和其他類型的值一樣,比較的結果可以被賦值給任意變量:
let result = 5 > 4; // 把比較的結果賦值給 result
alert( result ); // true
在比較字符串的大小時,JavaScript 會使用“字典(dictionary)”或“詞典(lexicographical)”順序進行判定。
換言之,字符串是按字符(母)逐個進行比較的。
例如:
alert( 'Z' > 'A' ); // true
alert( 'Glow' > 'Glee' ); // true
alert( 'Bee' > 'Be' ); // true
字符串的比較算法非常簡單:
在上面的第一個例子中,'Z' > 'A'
比較在算法的第 1 步就得到了結果。
在第二個例子中,字符串 Glow
與 Glee
的比較則需要更多步驟,因為需要逐個字符進行比較:
G
?和 ?G
? 相等。l
? 和 ?l
? 相等。o
? 比 ?e
? 大,算法停止,第一個字符串大于第二個。非真正的字典順序,而是 Unicode 編碼順序
在上面的算法中,比較大小的邏輯與字典或電話簿中的排序很像,但也不完全相同。
比如說,字符串比較對字母大小寫是敏感的。大寫的
"A"
并不等于小寫的"a"
。哪一個更大呢?實際上小寫的"a"
更大。這是因為在 JavaScript 使用的內部編碼表中(Unicode),小寫字母的字符索引值更大。我們會在 字符串 這章討論更多關于字符串的細節(jié)。
當對不同類型的值進行比較時,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
一個有趣的現象
有時候,以下兩種情況會同時發(fā)生:
- 若直接比較兩個值,其結果是相等的。
- 若把兩個值轉為布爾值,它們可能得出完全相反的結果,即一個是 ?
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
值,則會使用其他的類型轉換規(guī)則。
普通的相等性檢查 ==
存在一個問題,它不能區(qū)分出 0
和 false
:
alert( 0 == false ); // true
也同樣無法區(qū)分空字符串和 false
:
alert( '' == false ); // true
這是因為在比較不同類型的值時,處于相等判斷符號 ==
兩側的值會先被轉化為數字??兆址?nbsp;false
也是如此,轉化后它們都為數字 0。
如果我們需要區(qū)分 0
和 false
,該怎么辦?
嚴格相等運算符 ===
在進行比較時不會做任何的類型轉換。
換句話說,如果 a
和 b
屬于不同的數據類型,那么 a === b
不會做任何的類型轉換而立刻返回 false
。
讓我們試試:
alert( 0 === false ); // false,因為被比較值的數據類型不同
同樣的,與“不相等”符號 !=
類似,“嚴格不相等”表示為 !==
。
嚴格相等的運算符雖然寫起來稍微長一些,但是它能夠很清楚地顯示代碼意圖,降低你犯錯的可能性。
當使用 null
或 undefined
與其他值進行比較時,其返回結果常常出乎你的意料。
當使用嚴格相等 ===
比較二者時
它們不相等,因為它們屬于不同的類型。
alert( null === undefined ); // false
當使用非嚴格相等 ==
比較二者時
JavaScript 存在一個特殊的規(guī)則,會判定它們相等。它們倆就像“一對戀人”,僅僅等于對方而不等于其他任何的值(只在非嚴格相等下成立)。
alert( null == undefined ); // true
當使用數學式或其他比較方法 < > <= >=
時:
null/undefined
會被轉化為數字:null
被轉化為 0
,undefined
被轉化為 NaN
。
下面讓我們看看,這些規(guī)則會帶來什么有趣的現象。同時更重要的是,我們需要從中學會如何遠離這些特性帶來的“陷阱”。
通過比較 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
在相等性檢查 ==
中不會進行任何的類型轉換,它們有自己獨立的比較規(guī)則,所以除了它們之間互等外,不會等于任何其他的值。這就解釋了為什么(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
?相等,不會與其他值相等。我們?yōu)楹我芯可鲜鍪纠课覀冃枰獣r刻記得這些古怪的規(guī)則嗎?不,其實不需要。雖然隨著代碼寫得越來越多,我們對這些規(guī)則也都會爛熟于胸,但是我們需要更為可靠的方法來避免潛在的問題:
===
? 外,其他但凡是有 ?undefined/null
? 參與的比較,我們都需要格外小心。>= > < <=
? 去比較一個可能為 ?null/undefined
? 的變量。對于取值可能是 ?null/undefined
? 的變量,請按需要分別檢查它的取值情況。==
? 下,?null
?和 ?undefined
?相等且各自不等于任何其他的值。>
? 或 ?<
? 進行比較時,需要注意變量可能為 ?null/undefined
? 的情況。比較好的方法是單獨檢查變量是否等于 ?null/undefined
?。重要程度: 5
以下表達式的執(zhí)行結果是?
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
結果的原因:
"a"
? 比 ?"p"
? 小。"2"
? 大于 ?"1"
?。null
?只與 ?undefined
?互等。null
?只與 ?undefined
?相等。Copyright©2021 w3cschool編程獅|閩ICP備15016281號-3|閩公網安備35020302033924號
違法和不良信息舉報電話:173-0602-2364|舉報郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號
聯系方式:
更多建議: