JavaScript核心概念(1):型別轉換

桃翁發表於2018-08-07

本文首發於個人部落格

JavaScript核心概念(1):型別轉換

看到這個是不是有一種想打人的感覺,垃圾 JavaScript,這特麼都什麼鬼,相信很多人不管是筆試還是面試,都被 JS 的型別轉換難道過,相信認真看完我這篇文章,媽媽再也不用擔心型別轉換的問題了。

原始值到原始值的轉換

  1. 原始值轉化為布林值

    所有的假值(undefined、null、0、-0、NaN、””)會被轉化為 false,其他都會被轉為 true

  2. 原始值轉化為字串 都相當於 原始值 + ""

  3. 原始值轉為數字

    • 布林轉數字:true -> 1, false -> 0
    • 字串轉數字:以數字表示的字串可以直接會轉為字串,如果字串頭尾有空格會忽略,但是空格在中間,轉換結果就是 NaN。
      +" 66" // 66
      +" 6 7 " // NaN
    複製程式碼

原始值到物件的轉換

  • null 和 undefined 轉物件直接拋異常
  • 原始值通過呼叫 String()、Number()、Boolean()建構函式,轉換為他們各自的包裝物件

物件到原始值的轉換

  1. 物件轉為布林都為 true
  2. 物件到字串
    • 如果物件有 toString() 方法,就呼叫 toString() 方法。如果該方法返回原始值,就講這個值轉化為字串。
    • 如果物件沒有 toString() 方法或者 該方法返回的不是原始值,就會呼叫該物件的 valueOf() 方法。如果存在就呼叫這個方法,如果返回值是原始值,就轉化為字串。
    • 否則就報錯
  3. 物件到數字
    • 物件轉化為數字做了跟物件轉化為字串做了想同的事兒,不同的是後者是先呼叫 valueOf 方法,如果呼叫失敗或者返回不是原始值,就呼叫 toString 方法。
  4. 補充。一些常用內建物件 toString 方法和 valueOf 的轉換規則
    • toString 相關
      JavaScript核心概念(1):型別轉換
    • valueOf 相關
      JavaScript核心概念(1):型別轉換

== 運算子如何進行型別轉換

  1. 如果一個值是null,另一個值是undefined,則相等
  2. 如果一個是字串,另一個值是數字,則把字串轉換成數字,進行比較
  3. 如果任意值是true,則把true轉換成1再進行比較;如果任意值是false,則把false轉換成0再進行比較
  4. 如果一個是物件,另一個是數值或字串,把物件轉換成基礎型別的值再比較。物件轉換成基礎型別,利用它的 toString 或者 valueOf 方法。 js 核心內建類,會嘗試 valueOf 先於 toString(可以理解為物件優先轉換成數字);例外的是 Date,Date 利用的是 toString 轉換。非 js 核心的物件,通過自己的實現中定義的方法轉換成原始值。

+ 運算子如何進行型別轉化

  1. 如果作為一元運算子就是轉化為數字,常常用來將字串轉化為數字

    +"2" //  2
    2+false // 0
    複製程式碼
  2. 如果作為二元運算子就有兩種轉換方式

    • 兩邊如果有字串,另一邊一會轉化為字串進行相加
    • 如果沒有字串,兩邊都會轉化為數字進行相加,物件也根據前面的方法轉化為原始值數字。
    • 如果其中的一個運算元是物件,則將物件轉換成原始值,日期物件會通過 toString() 方法進行轉換,其他物件通過 valueOf()方法進行轉換,但是大多數方法都是不具備可用的 valueOf() 方法,所以還是會通過 toString() 方法執行轉換。

流程圖如下:

JavaScript核心概念(1):型別轉換

實戰分析

1. []+[] // ""

_1. 首先運算子是 + 運算子而且很明顯是二元運算子,並且有物件,所以選擇最後一點,運算元是物件,將物件轉換為原始值。

_2. 兩邊物件都是陣列,左邊的陣列先呼叫 valueOf() 方法無果,然後去呼叫 toString(), 方法,在 toString() 的轉化規則裡面有『將陣列轉化為字串,用逗號分隔』,由於沒有其他元素,所以直接是空字串 “”。

JavaScript核心概念(1):型別轉換

_3. 因為加號有一邊是字串了,所以另外一邊也轉為 字串,所以兩邊都是空字串 “”。

_4. 所以加起來也是空字串 “”。

2. (! + [] + [] + ![]).length // 9

_1. 首先我們會看到挺多一元運算子,「+」、「!」,對於一元運算子是右結合性,所以可以畫出以下運算順序。

JavaScript核心概念(1):型別轉換

_2. 對於+[],陣列是會被轉化為數字的而不是字串,可見「+ 運算子如何進行型別轉化」的第一條,所以經過第一步就會轉化為

(!0 + [] + false).length

_3. 第二步比較簡單,0 轉化為布林值就是 false,所以經過第二步就轉化為

(true + [] + false).length

_4. 第三步中間的 []會轉為空字串,在「+ 運算子如何進行型別轉化」第二條的第三點,物件會被轉轉化為原始值,就是空字元,所以經過第三步之後就會變成

("true" + false).length

_5. 第五步就比較簡單啦,最終就是

"truefalse".length // 9

附錄:

JavaScript核心概念(1):型別轉換
《JavaScript權威指南》中型別轉換表格

qrcode_for_gh_39aba8571ae1_258.jpg
個人公眾號,歡迎繼續交流

相關文章