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