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