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