摘要:具體的行為取決于參數的類型。說到,就不得不提一下方法,方法自帶隱式類型轉換,該方法在測試其參數之前,會先調用方法將其轉換為數字。全等運算符會先進行數據類型判斷,并且不會發生隱式類型轉換。
類型轉換還不行?還非得隱式?這是什么高級玩意?
廢話不多說,我們先上一盤?,額,不對,先看一個例子吧。
3 + true
實際上在大多數編程語言中,都會認為上面這個表達式是錯誤的。因為布爾表達式與算術運算是不兼容的。尤其是在靜態語言中,甚至不會被運行運行。即使是動態語言中,通常雖然可以讓程序運行,但是會拋出一個異常。
然而,然而, Javascript 不僅運行程序能夠正常運行,而且還會順利地產生結果 4。Javascript 真的是對類型錯誤出奇的寬容啊。看起來很像是一件好事對不對?
基本上,在 Javascript 中,只有在一些極少數情況下才會因為類型錯誤而拋出一個異常。諸如: 調用非函數對象或者獲取 null / undefined 的屬性時。
但是在大多數情況下,Javascript 都是不會拋出異常的。這個『小婊砸』反而按照多種多樣的轉換協議偷偷的強制轉換為她期望的值。諾,你看,還花樣轉換呢,真會玩嘛。這就是所謂的『隱式類型轉換』。
那么,上面那個例子中,究竟是發生了什么樣的轉換方式呢?
首先,Javascript 這個『小婊砸』在遇到算數運算符(- 、* 、/ 和 %)的時候會在運算之前將參與運算的雙方轉換成數字。
那么問題又來了,true 怎么就轉換成數字了呢?實際上我們通過 Number(true) 就可以看到, true 轉換為數字之后就是為 1,相反,false 轉換為數字之后就對應為 0。
細心的你可能發現我在上面并沒有提到 + 運算符,那是因為它更復雜。因為它既承擔著數字相加,又肩負著字符串連接操作的重任。具體的行為取決于參數的類型。
但是,如果一個數字和一個字符串相加,會碰撞出什么樣的火花呢?
顯然 Javascript 這個『小婊砸』更偏愛字符串多一點,她會將數字(toString())轉換為字符串,然后執行字符串連接操作。
例如:
"1" + 2; // "12" 1 + "2"; // "12"
但是,注意,Javascript 對操作順序非常敏感,以至于會發生這樣的事情:
1 + 2 + "3"; // "33"
因為加法運算是自左向右的,因此它等同于下面的表達式:
(1 + 2) + "3"; // "33"
再來看這一個例子:
if (1 == true) { alert("true"); } else { alert("false"); }
相信你一定輕松的猜到了結果對不對?
但是,哼,你以為我的問題會這么簡單么?那豈不是太小看你了。
我們都知道,Javascript 中,數字 0 為假,非0 均為真, 那么我想問的是,在上面的條件語句中,到底是 1 被隱式類型轉換了呢還是 true 被隱式類型轉換了呢?
實際上在條件判斷運算 == 中的轉換規則是這樣的:
如果比較的兩者中有布爾值(Boolean),會把 Boolean 先轉換為對應的 Number,即 0 和 1,然后進行比較。
如果比較的雙方中有一方為 Number,一方為 String時,會把 String 通過 Number() 方法轉換為數字,然后進行比較。
如果比較的雙方中有一方為 Boolean,一方為 String時,會將雙方轉換為數字,然后再進行比較。
如果比較的雙方中有一方為 Number,一方為Object時,則會調用 valueOf 方法將Object轉換為數字,然后進行比較。
例如:
1 == { valueOf: function() {return 1;} } // true 1 + { valueOf: function() {return 1;} } // 2
需要強調的是,在 Javascript 中,只有 空字符串、數字0、false、null、undefined 和 NaN 這 6 個值為假之外,其他所有的值均為真值。
說到 NaN,就不得不提一下 isNaN() 方法,isNaN() 方法自帶隱式類型轉換,該方法在測試其參數之前,會先調用 Number() 方法將其轉換為數字。所以 isNaN("1") 這個語句中明明用一個字符串去測試,返回值仍然為 false 也就不足為怪了。
在 + 號運算中還有一種更復雜的情況,那就是數字/字符串和對象進行運算的時候,上面已經舉例說明了數字和對象運算的情況,我們再來說一下字符串和對象運算的情況。
當字符串和對象進行 + 運算的時候,Javascript 會通過對象的 toString() 方法將其自身轉換為字符串,然后進行連接操作。
"1" + { toString: function() {return 1;} } // "11"
之所以說它特殊,是因為當一個對象同時包含 toString() 和 valueOf() 方法的時候,運算符 + 應該調用哪個方法并不明顯(做字符串連接還是加法應該根據其參數類型,但是由于隱式類型轉換的存在,類型并不顯而易見。),Javascript 會盲目的選擇 valueOf() 方法而不是 toString() 來解決這個問題。這就意味著如果你打算對一個對象做字符串連接的操作,但結果卻是......
var obj = { toString: function() { return "Object CustomObj"; }, valueOf: function() { return 1; } }; console.log("Object: " + obj); // "Object: 1"
隱式類型轉換會給我們造成很多麻煩,那么該怎么避免呢?
建議在所有使用條件判斷的時候都使用全等運算符 === 來進行條件判斷。全等運算符會先進行數據類型判斷,并且不會發生隱式類型轉換。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/78746.html
摘要:當一個值為字符串,另一個值為非字符串,則后者轉為字符串。文章出自的個人博客 showImg(https://segmentfault.com/img/bVEWkS?w=3376&h=1312); JavaScript 是一門弱類型語言,剛接觸的時候感覺方便快捷(不需要聲明變量類型了耶!),接觸久了會發現它帶來的麻煩有的時候不在預期之內 呵呵一笑,哪有這么夸張,可能有人看過這樣一段代碼 ...
摘要:中數字存儲使用的是位雙精度浮點數在計算機中存儲為位符號位正數負數指數位用來確定范圍尾數位用來確定精度轉成十進制表示法為符號位指數位尾數位偏正值使得指數位真實取值為而非目的是為了方便比較大小實際指數值階碼偏正值階碼指數的移碼移碼與補 Javascript中數字存儲使用的是IEEE754 64位雙精度浮點數 在計算機中存儲為64位1 11 521: 符號位 0正數 1負數11: 指數位 用...
摘要:歡迎大家收看聊一聊系列,這一套系列文章,可以幫助前端工程師們了解前端的方方面面不僅僅是代碼作為現代應用,的大量使用,使得前端工程師們日常的開發少不了拼裝模板,渲染模板。我們今天就來聊聊,拼裝與渲染模板的那些事兒。一改俱改,一板兩用。 歡迎大家收看聊一聊系列,這一套系列文章,可以幫助前端工程師們了解前端的方方面面(不僅僅是代碼):https://segmentfault.com/blog...
摘要:歡迎大家收看聊一聊系列,這一套系列文章,可以幫助前端工程師們了解前端的方方面面不僅僅是代碼作為現代應用,的大量使用,使得前端工程師們日常的開發少不了拼裝模板,渲染模板。我們今天就來聊聊,拼裝與渲染模板的那些事兒。一改俱改,一板兩用。 歡迎大家收看聊一聊系列,這一套系列文章,可以幫助前端工程師們了解前端的方方面面(不僅僅是代碼):https://segmentfault.com/blog...
摘要:歡迎大家收看聊一聊系列,這一套系列文章,可以幫助前端工程師們了解前端的方方面面不僅僅是代碼作為現代應用,的大量使用,使得前端工程師們日常的開發少不了拼裝模板,渲染模板。我們今天就來聊聊,拼裝與渲染模板的那些事兒。一改俱改,一板兩用。 歡迎大家收看聊一聊系列,這一套系列文章,可以幫助前端工程師們了解前端的方方面面(不僅僅是代碼):https://segmentfault.com/blog...
閱讀 2462·2021-11-23 09:51
閱讀 1872·2021-10-13 09:40
閱讀 1390·2021-09-30 10:01
閱讀 597·2021-09-26 09:46
閱讀 2256·2021-09-23 11:55
閱讀 1401·2021-09-10 10:51
閱讀 2266·2021-09-09 09:33
閱讀 2235·2019-08-29 17:25