摘要:即在這個隱式強制類型轉(zhuǎn)換中,即不會等于也不會等于。按照正常人類的腦回路,應(yīng)該是將先轉(zhuǎn)換為布爾值,然后再將兩個布爾值對比。為什么和就可以避開操作符的坑呢它們進行強制類型轉(zhuǎn)換時的轉(zhuǎn)換規(guī)則又是怎樣的。
在js中,類型轉(zhuǎn)換是一個被非常多人詬病的地方。新手看了會發(fā)矇,老手看了會頭疼。
類型轉(zhuǎn)換,又成為強制類型轉(zhuǎn)換,主要區(qū)分為顯式強制類型轉(zhuǎn)換和隱式強制類型轉(zhuǎn)換
按我理解,類型轉(zhuǎn)換的意思就很明顯,就是當(dāng)程序運行時需要此刻的變量的類型與變量的實際類型不符時,就會進行強制轉(zhuǎn)換,在一些靜態(tài)語言中,這個過程發(fā)生在編譯階段,或者干脆就拋出錯誤。而在js中,這個轉(zhuǎn)換過程發(fā)生在運行時,所以你寫代碼的時候并不會意識到自己已經(jīng)掉進坑里了。
而顯式強制類型轉(zhuǎn)換,簡單的說,就是你覺得你可以明面上一眼看出來的,比如‘’ + number,+string,Boolean(value); 而隱式強制類型轉(zhuǎn)換就是反過來的意思。
舉個栗子:
var a = "value"; if (a == true) { console.log("a is true"); } else if (a == false) { console.log("a is false"); }
按照正常的腦回路,一般人不會這么寫。但是確實是有人會寫if (a == true) {...}這種語句,當(dāng)然,后面的else if (a == false)是為了節(jié)目效果加的。即便是這樣,a == true這種寫法也是不可取的。
最后的輸出是,兩個都不輸出。即在這個隱式強制類型轉(zhuǎn)換中,a即不會等于true, 也不會等于false。
首先解釋一下為什么a既不等于true, 也不等于false。按照正常人類的腦回路,應(yīng)該是將a先轉(zhuǎn)換為布爾值,然后再將兩個布爾值對比。這種情況下,a轉(zhuǎn)成布爾值只能轉(zhuǎn)換成true或者false。要是這么想,那你就是too young, too simple了
當(dāng)使用相等操作符==進行判斷時,將遵循以下規(guī)則(來自紅寶書):
· 如果又一個操作數(shù)是布爾值,則在比較相等性之前先將其轉(zhuǎn)換為數(shù)值(false轉(zhuǎn)換為0,而true轉(zhuǎn)換為1
· 如果一個操作數(shù)是字符串,另一個操作數(shù)是數(shù)值,在比較相等性之前先將字符串轉(zhuǎn)換為數(shù)值
· 如果一個操作數(shù)是對象,另一個操作數(shù)不是,則調(diào)用對象的valueOf()方法,用得到的基本類型值按照之前的規(guī)則進行比較
· null和undefined是相等的
· 要比較相等性之前,不能將null和undefined轉(zhuǎn)換成其他任何值
· 如果一個操作數(shù)是NaN,則相等操作符返回false。
· 如果兩個操作數(shù)都是對象,則比較它們是不是同一個對象,是則返回true,否則返回false
所以就可以知道上例中,轉(zhuǎn)換是如何進行的。首先兩個相等操作的操作數(shù)中都包含布爾值,先將布爾值轉(zhuǎn)換為數(shù)值所以這里true轉(zhuǎn)換為1,false轉(zhuǎn)換為0。接下來再次進行比較,此時兩對操作數(shù)中都包含一個字符串操作數(shù),則將字符串轉(zhuǎn)換為數(shù)值, a轉(zhuǎn)換為數(shù)值是NaN,此時再次進行比較,由于有一個操作數(shù)是NaN,按照規(guī)則,返回false。所以a既不等于true也不等于false。
由上可以看出,使用==進行條件判斷的時候是非常具有危險性的,尤其是當(dāng)其中一個操作數(shù)為true的時候,如果另一個操作數(shù)不為布爾值,則很有可能就掉進坑里了。
那么一般在判斷的時候怎么去進行判斷比較好呢。我認(rèn)為盡量不使用==操作符。使用===進行全等判斷,或者直接將你需要判斷的值丟進if判斷里,比如if (a == true)可以改成if (a)或者if (!!a)這樣就能避開==操作符的坑了。如果一定要使用==進行比較,不用不舒服,則最好先將操作數(shù)進行顯式類型轉(zhuǎn)換為同一類型的數(shù)據(jù),再進行比較,
知其然就要知其所以然。
為什么if (a)和if (!!a)就可以避開==操作符的坑呢?它們進行強制類型轉(zhuǎn)換時的轉(zhuǎn)換規(guī)則又是怎樣的。
其實在if的判斷語句塊內(nèi),如果判斷值不是布爾值的話,會自動調(diào)用Boolean()函數(shù)進行布爾值的轉(zhuǎn)換。而!!則相當(dāng)于一次Boolean()的值類型轉(zhuǎn)換了。所以在if的判斷語句里直接放入判斷條件和顯式的將判斷條件進行轉(zhuǎn)換,其作用是一樣的。區(qū)別也只是在于是否對后續(xù)看代碼的人友好了,如果后面代碼維護可能是接觸代碼不深的新手,則建議進行顯式的轉(zhuǎn)換。
由上面的解釋可以知道if (a)和if (!!a),if (Boolean(a))的作用是一樣的,所以這里只要了解一下Boolean()函數(shù)的轉(zhuǎn)換規(guī)則就可以了:
任何非空字符串為true,空字符串("")為false
任何非零數(shù)字值(包括無窮大)為true,0和NaN為false
任何對象為true,null為false
undefined為false
以上規(guī)則來自紅寶書,部分內(nèi)容省略
看以上的Boolean()函數(shù)的轉(zhuǎn)換規(guī)則,與我們?nèi)粘9ぷ髦兴枰念愋娃D(zhuǎn)換是非常契合的。
比如我們普遍會認(rèn)為并要求if可以攔截空字符串,false,null,undefined,0與NaN
需要注意的是,雖然紅寶書上并沒明確指出,但三元運算符( ? : )使用的轉(zhuǎn)換規(guī)則也是Boolean()函數(shù)的轉(zhuǎn)換規(guī)則.
而除了條件判斷,在其他一些操作里也會出現(xiàn)類型轉(zhuǎn)換,比如關(guān)系操作符(<, >, <=, >=):
var a = "23"; var b = "3"; console.log(a < b); // true
上面這個轉(zhuǎn)換可能很多的前端開發(fā)工程師都掉進過坑里并摸不著頭腦。
可能你也看出來了出現(xiàn)‘23’小于‘3’的原因或許是在于它們都是字符串。如果關(guān)系操作符(<,>,<=,>=)兩邊都是字符串,則比較兩個字符串對應(yīng)的字符編碼。"2"的字符編碼是50,而3的字符編碼是51,所以這里出現(xiàn)了‘23’小于‘3’的情況。
到這里很多人都會驚嘆一聲,并表示記住了此知識點。但是這樣往往是不夠的,你需要深挖下去,需要確切的了解關(guān)系操作符的轉(zhuǎn)換規(guī)則,才能確保不會再次掉進它的坑里。
如果兩個操作數(shù)都是數(shù)值,則執(zhí)行數(shù)值比較 如果兩個操作數(shù)都是字符串,則比較兩個字符串對應(yīng)的字符編碼值
如果一個操作數(shù)是數(shù)值,則將另一個操作數(shù)轉(zhuǎn)換為一個數(shù)值,然后執(zhí)行數(shù)值比較
如果一個操作數(shù)是對象,則調(diào)用這個對象的valueOf()方法,并用得到的結(jié)果根據(jù)前面的規(guī)則進行比較
如果一個操作數(shù)是布爾值,則先將其轉(zhuǎn)換為數(shù)值,然后再執(zhí)行比較
如果一個操作數(shù)是NaN,undefined,則返回false
如果操作數(shù)為null, "", 則轉(zhuǎn)換為0進行比較
多看看紅寶書就會發(fā)現(xiàn)js中的類型轉(zhuǎn)換其實坑還是很多的,還有一些加減乘除的操作符本身也會產(chǎn)生類型轉(zhuǎn)換的問題。但是基本問題不是太大,所以就不多帶帶拎出來了。
最后,一道思考題:
// do something ... console.log(typeof a); // "object" console.log(a == false); // true
上面的對象為什么會等于false,這個題是之前刷到的一道面試題,可不是我瞎編的。。
最后,歡迎斧正,沒有仔細(xì)的準(zhǔn)備,所以寫的少且雜,也是作為自己的一個總結(jié)回顧吧。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/105183.html
摘要:所以就說說吧優(yōu)點可自定義動畫效果,支持隊列動效支持回調(diào)函數(shù)支持動畫的,等等功能缺點缺少自定義特效文檔比較少使用遇到的小問題默認(rèn)不是勻速的,需要設(shè)置詳細(xì)整理待續(xù) 在最近一段時間的工作里,常常用到動畫,我主要接觸了三個 animate.cssanimevelocity 下面分析一下他們的優(yōu)缺點 animate.css 優(yōu)點:animate.css主要是使用css實現(xiàn)動畫效果,目前已經(jīng)有幾十...
摘要:的單向數(shù)據(jù)傳遞直接作為一個本地變量下面是我的子組件這是父組件給我傳的數(shù)據(jù)運行結(jié)果如下圖子組件向父組件傳遞數(shù)據(jù)基本使用子組件向父組件傳遞數(shù)據(jù),不能像上面一樣實時的傳遞數(shù)據(jù),必須通過事件觸發(fā)。 組件是Vue核心功能之一,合理的組件化,可以減少我們代碼的冗余,提高項目的可維護性。下面,我將由淺入深的講Vue的組件在講之前,首先我們先了解一下組件的命名。 HTML是對特征名不敏感的語言,他...
摘要:然而有時候的結(jié)果和預(yù)期結(jié)果還是有些差異的。中文的可以通過來獲取。啊次比例中毓比侊啊比侊比例次毓中當(dāng)然和允許傳入?yún)?shù)指定,有興趣的可以去上看看用法。對于中文或者需要本地化比較的場景下,可以使用或者來進行比較。 大家都知道 js 自帶了一個排序方法 sort,很多時候需要排序的時候也都直接使用了 sort 方法來排序。然而有時候 sort 的結(jié)果和預(yù)期結(jié)果還是有些差異的。 看下面的代碼 [...
摘要:核心內(nèi)置類,會嘗試先于可以理解為對象優(yōu)先轉(zhuǎn)換成數(shù)字例外的是,利用的是轉(zhuǎn)換。非核心的對象,通過自己的實現(xiàn)中定義的方法轉(zhuǎn)換成原始值。 本文首發(fā)于個人博客 showImg(https://segmentfault.com/img/remote/1460000015954811?w=639&h=724); 看到這個是不是有一種想打人的感覺,垃圾 JavaScript,這特么都什么鬼,相信很多...
摘要:的目標(biāo)是對高級程序中間表示的適當(dāng)?shù)图壋橄?,即代碼旨在由編譯器生成而不是由人來寫。表示把源代碼變成解釋器可以運行的代碼所花的時間表示基線編譯器和優(yōu)化編 WebAssembly 那些事兒 什么是 WebAssembly? WebAssembly 是除 JavaScript 以外,另一種可以在網(wǎng)頁中運行的編程語言,并且相比之下在某些功能和性能問題上更具優(yōu)勢,過去我們想在瀏覽器中運行代碼來對網(wǎng)...
閱讀 3000·2021-10-19 11:46
閱讀 991·2021-08-03 14:03
閱讀 2952·2021-06-11 18:08
閱讀 2923·2019-08-29 13:52
閱讀 2778·2019-08-29 12:49
閱讀 497·2019-08-26 13:56
閱讀 937·2019-08-26 13:41
閱讀 861·2019-08-26 13:35