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