1. 程式人生 > >JavaScript型別轉換

JavaScript型別轉換

在這裡插入圖片描述

1.原始值到原始值的轉換

1.原始值轉化為布林值

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

2.原始值轉化為字串

都相當於 原始值 + “”

注意:null和undefined這兩個值沒有toSting()方法,但是可以通過+""方法或者通過String()函式轉換成字串。

var a = null+" "
typeof a   //string

var b = String(null);
typeof b   //string

x+""相當於 String(x)。

3.原始值轉化為數字

+" 66" // 66
+" 6 7 " // NaN

布林轉數字:true -> 1, false -> 0
字串轉數字:以數字表示的字串可以直接會轉為字串,如果字串頭尾有空格會忽略,但是空格在中間,轉換結果就是 NaN。

2.原始值到物件的轉換

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

3.物件到原始值的轉換

1.物件轉化為布林都為true

2.物件到字串:

如果物件有 toString() 方法,就呼叫 toString() 方法。如果該方法返回原始值,就講這個值轉化為字串。
如果物件沒有 toString() 方法或者 該方法返回的不是原始值,就會呼叫該物件的 valueOf() 方法。如果存在就呼叫這個方法,如果返回值是原始值,就轉化為字串。

3.物件到數字

物件轉化為數字做了跟物件轉化為字串做了想同的事兒,不同的是後者是先呼叫 valueOf 方法,如果呼叫失敗或者返回不是原始值,就呼叫 toString 方法。

4.補充
一些常用內建物件toString方法和valueOf的轉換規則。

toString相關:
在這裡插入圖片描述

valueOf相關:
在這裡插入圖片描述

附註:![]轉換成!true,但是[]轉換成0,[true]轉換成1.[]非空就轉換成1

在這裡插入圖片描述

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

1.如果一個值是null,另一個值是undefined,則相等

2.如果一個是字串,另一個值是數字,則把字串轉換成數字,進行比較

3.如果任意值是true,則把true轉換成1再進行比較;如果任意值是false,則把false轉換成0再進行比較

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

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

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

+"2"   //2
+false   //0

2.如果作為二元運算子就有兩種轉換方式

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

流程圖如下:

在這裡插入圖片描述

6.實戰分析

1.[]+[] // ""

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

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

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

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

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

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

在這裡插入圖片描述

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

(!0 + [] + “false”).length

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

(true + [] + “false”).length

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

(“true” + “false”).length

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

附錄:

在這裡插入圖片描述

下面是一些補充:

1.對資料型別有期待的語句和表示式:

1、期待boolean型別的 : if 語句 、 do while 語句 、 while do 語句 、 && || ! (與或非邏輯表示式) 、 ? : ( 三目運算子)

2、期待number型別的 : + - * / % (算數運算子) 、 ++ – (增量/減量運算子) 、 > 、 >= 、 < 、 <= 數字比較

3、期待字串的: + (字串連線) 、 > 、 >= 、 < 、 <= 字母排序比較

4、特殊的 : == 、 != (不)相等運算子,在檢測兩個運算元是否相等時,會進行型別轉換;(注意 : === 、!== 是(不)嚴格相等運算子,是不會進行型別轉換的)

需要說明的是,1中當然可以傳入表示式,但是表示式返回的結果也肯定會返回boolean型別的值,或者返回值被轉換為boolean;2和3有一些重複的運算子 : + 、 > 、 >= 、 < 、 <= ,這些運算子在不同場景下發生自動轉換的時候,會有不同的優先順序。

有如下場景:

1 + 1   // 2  
'1' + '1'  // '11' 
'1' + 1   // "11"
'1' + null   //  "1null"
'1' + {}   //  "1[object Object]"
'1' + new Date()  //  "1Wed Jun 20 2018 11:49:55 GMT+0800 (中國標準時間)"
1 + {}   // "1[object Object]"
1 + new Date()  //  "1Wed Jun 20 2018 11:56:56 GMT+0800 (中國標準時間)"
1 + []   //  "1"
1 + null  // 1

從例子中可以看到,+ 的轉換其實是優先轉換為字串的,如果有一個運算元是物件的話,會轉化為原始值(除了Date物件是呼叫toString()方式轉換 , 其他物件都會呼叫 valueOf() 進行轉換 , 但是由於多數物件只是簡單的繼承了valueOf() , 只會返回物件,而不是一個原始值,所以會再呼叫toString進行轉換) , 所以這裡可以簡單的理解為:都會轉換為字串 。 另一個運算元也會轉換為字串.

“+”還有特殊的用法,就是轉換為數字,如下。

+ null   //  0
+ undefined  //  NaN
+ {}  //  NaN
+ new Date()  //  1529467646682
+ ["5"]  //  5
+ "4"  //  4

+{}   //NaN
+[]   //0

> 、 >= 、 < 、 <= 這些比較運算子的規則和 + 類似,不過是會優先轉換為數字進行比較。

// 作用 : 比較數值大小或者再字母表中的位置。也是期待數字和字串!
1、兩個運算元中只要有一個不是字串,則兩個值都轉為數字 
"3" > "11"    //  true   字串比較
3 > "11"      // false   11 轉換為數字 
true > '0'    // true true 和 ‘0’ 都轉換為數字 
2、物件同樣會轉換為原始值(不過這裡的Date物件也是優先呼叫valueOf ,返回的是毫秒數,其他的和上述 + 的一樣),如果轉換後有一個字不是字串,則兩個值也都需要轉換為數字    

1000 > new Date()  // false
100000000000000000000000 > new Date()  //  true   date物件轉換為數字
"100000000000000000000000" > new Date()  //  true  左值也隨著 date物件一起轉換為數字
'11' > ["3"]  //  false  陣列轉為字串,所以這裡是字串比較