摘要:正確的解釋是允許在相等比較中進行強制類型轉換,而不允許。參考資料小議下字符串比較大小中的強制類型轉換核心概念類型轉換對象和方法隱式類型轉換小結
開胃菜
先說一個題外話,我在工作中遇到一個問題,需要比較 "08:00" 和 "09:00" 的大小,最后我找到三種方法:
在兩個字符串前后各拼接相同的年月日和秒,拼成完整的時間格式進行比較:
var head = "2016-01-01 " var foot = ":00" var time1 = head + "08:00" + foot //"2016-01-01 08:00:00" var time2 = head + "09:00" + foot //"2016-01-01 09:00:00"
剩下的就不說了,比較兩個完整的日期還是很容易的。
把兩個字符串中的冒號去掉,轉換成數字進行比較:
function timeToNumber(time) { let [head,foot] = time.split(":") return Number(head+foot) } var time1 = timeToNumber("08:00") //800 var time2 = timeToNumber("09:00") //900
直接比較
對,你沒有看錯,直接比較兩個字符串:
"08:00" > "09:00" //false
看到這里估計有人就納悶了,很明顯第三種方法是更簡潔的,但是字符串比較,好像很少見,它比較的依據是什么呢?
其實,字符串比較大小,會從左到右依次取兩個字符串中的字符,兩兩比較他們charCodeAt()的結果,直到比較出大小就停止。比如:
var str1 = "a11" var str2 = "a2" // str1 和 str2 比較的時候,會先比較 str1[0] 和 str2[0],兩個都是 "a",比較下一個 // str1[1] 是"1",charCodeAt()是49,str2[1] 是"2",結果是50,所以 str1[1] < str2[1],對比結束 // 最終結果 str1 < str2
同理,在比較"08:00" 和 "09:00"的時候,先比較兩個"0",發現一致之后比較"8"和"9",所以"08:00" < "09:00"。
這里有一個問題就是,時間格式必須保持一致,位數不夠的記得補"0",拿"8:00"和"10:00"比較會發現結果有問題,必須拿"08:00"和"10:00"比較才可以。
這個問題就說到這里,大家有其他的方法可以留言補充,給大家提供不同的思路。開胃菜結束,進入正題。
正題作為一個愛(記)學(不)習(清)的好(笨)孩子,通過字符串比較這件事,我意識到還有更多的非相同類型的比較,比如字符串和數字的比較,布爾和數組的比較(我瘋了么我這么用),另外還有加減乘除等其他操作符。
我覺得有必要整理一下了。
我第一反應是這張圖:
真是迷人的笑容呢 :)
在比較之前,我們需要先了解下各種數據類型轉化的結果有哪些。
轉數字
字符串:
空字符串是0
字符串頭尾有空格會忽略
空格在中間,或者字符串中含有非數字類型字符,轉換結果就是NaN
布爾:true -> 1, false -> 0
undefined字: NaN
null: 0
數組:
空數組是0
如果數組中有且只有一項是數字元素,轉換為數字
其他情況NaN
對象:
如果對象有valueOf()方法,就調用該方法。如果返回基本類型值,就將這個值轉化為數字
如果對象沒有valueOf()方法或者該方法返回的不是基本類型值,就會調用該對象的toString()方法。如果存在且返回值是基本類型值,就轉化為數字
否則就報錯
函數:NaN
轉字符串undefined -> "undefined"
null ->"null"
true -> "true" / false ->"false"
數字:極小和極大的數字使用指數形式,一般的情況你懂得
對象:
如果對象有toString()方法,就調用toString()方法。如果該方法返回基本類型值,就將這個值轉化為字符串
如果對象沒有toString()方法或者該方法返回的不是基本類型值,就會調用該對象的valueOf()方法。如果存在且返回值是基本類型值,就轉化為字符串
否則就報錯
除非自行定義,否則toString()返回內部屬性[[Class]]的值,如"[object Object]"
轉布爾所有的假值(undefined、null、+0、-0、NaN、"")會被轉化為 false,其他都會被轉為true
所以,空對象、空數組都是true
轉對象null和undefined轉對象直接拋異常
基本類型通過調用String()、Number()、Boolean()構造函數,轉換為他們各自的包裝對象
使用場景知道了各種數據類型轉化的規則,那么在不同的場景中,究竟是怎么使用的呢?
== 運算符常見的誤區是:==檢查值是否相等,===檢查值和類型是否相等。
正確的解釋是:==允許在相等比較中進行強制類型轉換,而===不允許。
事實上,==和===都會檢查操作數的類型,區別在于類型不同時它們的處理方式不同。
如果一個值是null,另一個值是undefined,則相等
如果一個是字符串,另一個值是數字,則把字符串轉換成數字,進行比較
如果任意值是true,則把true轉換成1再進行比較;如果任意值是false,則把false轉換成0再進行比較
如果一個是對象,另一個是數值或字符串,把對象轉換成基礎類型的值再比較
對象轉基礎類型時,優先調用valueOf(),再調用toString()。
例外的是Date,Date 利用的是toString()轉換
經典題[] == false // true !![] // true //原因是 == 兩邊都轉為數字進行比較,而不是 [] 轉為布爾值與 false 比較+ 運算符
+ 運算符可以作為一元運算符使用,此時的作用是將后邊跟著的數據轉為數字
+true // 1 +[] // 0 +new Date() //獲取當前時間的Unix時間戳
在作為二元運算符使用時,+運算符比- * /運算符要復雜一些,因為其他的運算符都是處理數字的,而+運算符還可以處理字符串拼接。
兩邊如果有字符串,另一邊會轉化為字符串進行相加
如果沒有字符串,兩邊都會轉化為數字進行相加,對象也根據前面的方法轉化為數字
如果其中的一個操作數是對象,則將對象轉換成原始值,日期對象會通過 toString()方法進行轉換,其他對象通過valueOf()方法進行轉換,但是大多數都是不具備可用的valueOf()方法,所以還是會通過toString()方法執行轉換
簡單來說就是,如果+運算符的其中一個操作數是字符串(或者通過以上步驟可以得到字符串),那么就執行字符串拼接,否則執行數字加法。
經典題!+[]+[]+![] //"truefalse" //首先第一個 + 左邊不是數值,所以它是一元運算符,將后邊跟著的 [] 轉化為數字 0 //同時,最后一個 [] 左邊是 ! 運算符,將 [] 轉化為布爾值并取反,為 false //轉化后的結果為 !0 + [] + false //!0 結果為 true,[] 轉化為 "",所以結果變為 true + "" + false //因為 第一個 + 右邊有字符串,所以變為"true" + false //最終結果為 "truefalse"條件判斷
以下條件判斷的語句,會發生隱式轉換為布爾值的情況:
if()語句中的條件判斷表達式
for(..; ..; ..)語句中的條件判斷表達式
while()和do .. while()
? : 中的條件判斷表達式
||和&&左邊的操作數
補充:valueOf()和toString()常用內置對象調用toString()和valueOf()的返回情況
類型 | toString | valueOf |
---|---|---|
Object | "[object 類型名]" | 對象本身 |
String | 字符串值 | 字符串值 |
Number | 返回數值的字符串表示。還可返回以指定進制表示的字符串,默認10進制 | 數字值 |
Boolean | "true" / "false" | Boolean 值 |
Array | 每個元素轉換為字符串,用英文逗號作為分隔符進行拼接 | 數組本身 |
Date | 日期的文本表示,格式為Wed Jun 05 2019 18:22:32 GMT+0800 (中國標準時間) | 返回時間戳,等同于調用getTime() |
Function | 函數的文本表示 | 函數本身 |
RegExp | 正則的文本表示 | 正則本身 |
以上是本篇文章的內容,歡迎大家提出自己的想法,我們一起學習進步,與君共勉。
參考資料小議js下字符串比較大小
JavaScript中的強制類型轉換
JavaScript核心概念(1):類型轉換
js對象tostring和valueof方法
JavaScript隱式類型轉換小結
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/104472.html
摘要:在各大瀏覽器廠商的發展過程中,它們對的標準各有不同的實現,標準不同存在差異所以產生兼容性的問題。它是一種對特定的瀏覽器或瀏覽器組顯示或隱藏規則或聲明的方法。但是及更低版本瀏覽器會繼續解析。 為什么會存在瀏覽器兼容問題? 首先要了解兼容,我們先得了解一下為什么會存在瀏覽器兼容問題。在各大瀏覽器廠商的發展過程中,它們對web的標準各有不同的實現,標準不同存在差異所以產生兼容性的問題。 瀏覽...
摘要:配置涵蓋了目前的業務場景的基本需求,但是可擴展性很低。最終決定采用的生態鏈來解決上述遇到的問題。在指定的路徑下寫入對應的文件。 大綱 遇到的問題場景及解決方案對比 什么是babel? 解決過程 目前遺留的問題 目前實現功能API 參考 遇到的問題場景及解決方案對比 我們目前采用的是antd + react(umi)的框架做業務開發。在業務開發過程中會有較多頻繁出現并且相似度很高的場...
閱讀 1398·2021-10-11 10:58
閱讀 1482·2021-09-04 16:41
閱讀 679·2019-08-30 15:55
閱讀 804·2019-08-29 18:46
閱讀 3145·2019-08-29 14:05
閱讀 3531·2019-08-26 14:00
閱讀 2455·2019-08-26 13:53
閱讀 3179·2019-08-26 13:29