banner
isolcat

isolcat

I am not afraid of storms, for I am learning how to sail my ship
github

一篇文章搞定JavaScript隱式轉換

前言#

js 由於眾多歷史遺留原因,對於類型的把控沒有那麼強 (這也就促成了 typescript 的誕生),在日常的開發和刷八股文的時候,常常會被 js 的一些隱式轉換給折磨的不成人樣,即使是老 js 人有時候都會犯一些錯,這篇文章將直接覆蓋 js 的所有隱式轉換情況,直接讓你一篇就搞定 JavaScript 的隱式轉換

一張圖查看 js 地獄般的隱式轉換:how-it-fucking-work

1. 減、乘、除#

⭐️我們在對各種非Number類型運用數學運算符 (- * /) 時,會先將非Number類型轉換為Number類型。

1 - true // 0, 首先把 true 轉換為數字 1, 然後執行 1 - 1
1 - null // 1,  首先把 null 轉換為數字 0, 然後執行 1 - 0
1 * undefined //  NaN, undefined 轉換為數字是 NaN
2 * ['5'] //  10, ['5']首先會變成 '5', 然後再變成數字 5

上面例子中的 ['5'] 的轉換,涉及到拆箱操作,將來有機會再出一篇文章說明。

2. 加法的特殊性#

⭐️為什麼加法要區別對待?因為 JS 裡 +還可以用來拼接字符串。謹記以下 3 條:

  • 當一側為String類型,被識別為字符串拼接,並會優先將另一側轉換為字符串類型。
  • 當一側為Number類型,另一側為原始類型,則將原始類型轉換為Number類型。
  • 當一側為Number類型,另一側為引用類型,將引用類型和Number類型轉換成字符串後拼接。

⭐️以上 3 點,優先級從高到低,即 3+'abc' 會應用規則 1,而 3+true會應用規則 2。

123 + '123' // 123123   (規則1)
123 + null  // 123    (規則2)
123 + true // 124    (規則2)
123 + {}  // 123[object Object]    (規則3)

邏輯語句中的類型轉換#

當我們使用 if while for 語句時,我們期望表達式是一個Boolean,所以一定伴隨著隱式類型轉換。而這裡面又分為兩種情況:

1. 單個變量#

⭐️如果只有單個變量,會先將變量轉換為 Boolean 值。

我們可以參考附錄的轉換表來判斷各種類型轉變為Boolean後的值。

不過這裡有個小技巧:

只有 null undefined '' NaN 0 false 這幾個是 false,其他的情況都是 true,比如 {} , []

2. 使用 == 比較中的 5 條規則#

雖然我們可以嚴格使用 ===,不過了解==的習性還是很有必要的。

⭐️根據 == 兩側的數據類型,我們總結出 5 條規則:

  • 規則 1:NaN和其他任何類型比較永遠返回false(包括和他自己)。
NaN == NaN // false
  • 規則 2:Boolean 和其他任何類型比較,Boolean 首先被轉換為 Number 類型。
true == 1  // true 
true == '2'  // false, 先把 true 變成 1,而不是把 '2' 變成 true
true == ['1']  // true, 先把 true 變成 1, ['1']拆箱成 '1', 再參考規則3
true == ['2']  // false, 同上
undefined == false // false ,首先 false 變成 0,然後參考規則4
null == false // false,同上
  • 規則 3:StringNumber比較,先將String轉換為Number類型。
123 == '123' // true, '123' 會先變成 123
'' == 0 // true, '' 會首先變成 0

規則 4:null == undefined比較結果是true,除此之外,nullundefined和其他任何結果的比較值都為false

null == undefined // true
null == '' // false
null == 0 // false
null == false // false
undefined == '' // false
undefined == 0 // false
undefined == false // false

規則 5:原始類型引用類型做比較時,引用類型會依照ToPrimitive規則轉換為原始類型。

⭐️ToPrimitive規則,是引用類型向原始類型轉變的規則,它遵循先valueOftoString的模式期望得到一個原始類型。

如果還是沒法得到一個原始類型,就會拋出 TypeError

'[object Object]' == {} 
// true, 對象和字符串比較,對象通過 toString 得到一個基本類型值
'1,2,3' == [1, 2, 3] 
// true, 同上  [1, 2, 3]通過 toString 得到一個基本類型值

通過幾個特別的題目來練習一下吧!#

1. [] == ![]

	- 第一步,![] 會變成 false
	- 第二步,應用 規則2 ,題目變成: [] == 0
	- 第三步,應用 規則5 ,[]的valueOf是0,題目變成: 0 == 0
	- 所以, 答案是 true !//

2. [undefined] == false#

	- 第一步,應用 規則5 ,[undefined]通過toString變成 '',
	  題目變成  '' == false
	- 第二步,應用 規則2 ,題目變成  '' == 0
	- 第三步,應用 規則3 ,題目變成  0 == 0
	- 所以, 答案是 true !
	// 但是 if([undefined]) 又是個true!

3. 更多的題目#

更多的練習,大家去生活中去發現吧。(悲慘的生活)

⭐️強烈建議大家去找各種奇奇怪怪的題目,反復練習上面 5 條規則,直到爛熟於心。

附錄 1:類型轉換表#

這個表老實用了,在執行上面提到的轉換規則時,可以參考這個對照表。

convert-table

載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。