數據類型的強制轉換和隱式轉換

數據類型的分類

數據類型的分類:基本數據類型引用數據類型segmentfault

強制轉換

強制轉換主要指使用一些特定函數,手動將各類類型的值,轉換爲其對應的類型。數組

Number()

使用 Number() 函數,能夠將任意類型的值轉化成數值。根據參數的數據類型不一樣會有不一樣的結果。模塊化

參數是基本數據類型時

1. 數值:轉換後仍是原來的值函數

Number(36)      // 36

2. 字符串code

  • 含有非數值的字符串,返回 NaN。比 parseInt 函數嚴格不少,只要有一個字符沒法轉爲數值,整個字符串就會被轉爲 NaN
  • 只含有數值,則轉換爲相應的數值。
  • 空字符串轉爲 0
  • 會自動過濾字符串開頭和結尾的空格。
Number('\n  36  \t')  // 36
Number('36abc')       // NaN
Number('')            // 0

3. 布爾值對象

  • true 轉爲 1
  • false 轉爲 0
Number(true)       // 1
Number(false)      // 0

4. undefined 和 nullip

  • undefined 轉爲 NaN
  • null 轉爲 0
Number(undefined)    // NaN
Number(null)         // 0

參數是引用類型時

Number() 方法的參數是對象時,若是該對象是包含單個數值的數組,則返回該數值;不然返回 NaN字符串

Number({a: 1}) // NaN
Number([1, 2, 3]) // NaN
Number([5]) // 5

轉換規則get

  • 第一步:調用對象自身的 valueOf() 方法。若是返回原始類型的值,則直接對該值使用 Number() 函數,再也不進行後續步驟。
  • 第二步:若是 valueOf() 方法返回的仍是對象,則改成調用對象自身的 toString() 方法。若是返回原始類型的值,則直接對該值使用 Number() 函數,再也不進行後續步驟。
  • 第三步:若是 toString() 方法返回的仍是對象,就報錯。

默認狀況下,對象的 valueOf() 方法返回對象自己,因此通常老是會調用 toString() 方法,而 toString() 方法返回對象的類型字符串,好比 [object Object]。所以對字符串使用 Number() 函數,就返回 NaNstring

let obj1 = {
  valueOf: function () { return 3; }
}

let obj2 = {
  toString: function () { return 6; }
}

let obj3 = {
  valueOf: function () { return 3; },
  toString: function () { return 6; }
}

Number(obj1)     // 3
Number(obj2)     // 6
Number(obj3)     // 3

String()

String() 函數能夠將任意類型的值轉化成字符串。根據參數的數據類型不一樣會有不一樣的結果。

參數是基本數據類型時

統一轉換爲對應的字符串形式。

String(123)         // "123"
String('abc')       // "abc"
String(true)        // "true"
String(undefined)   // "undefined"
String(null)        // "null"

參數是引用類型時

  • 參數是對象時,返回一個類型字符串。
  • 參數是數組時,則將數組轉爲 , 逗號鏈接的字符串;[] 空數組轉換爲 '' 空字符串。
  • 參數是其它引用類型時(正則,Date,function等),返回對應的字符串形式。
String({})              // "[object Object]"
String([1, 2, 3])       // "1,2,3"
String([])              // ""
String(/dora/)          // "/dora/"
String(new Date())      // "Fri Nov 22 2019 14:14:29 GMT+0800 (中國標準時間)"
String(function a(){})  // "function a(){}"

轉換規則

轉換規則,與 Number() 方法基本相同,只是互換了 valueOf() 方法和 toString() 方法的執行順序。

  • 第一步:先調用對象自身的 toString() 方法。若是返回原始類型的值,則對該值使用 String() 函數,再也不進行如下步驟。
  • 第二步:若是 toString() 方法返回的是對象,再調用原對象的 valueOf() 方法。若是 valueOf() 方法返回原始類型的值,則對該值使用 String() 函數,再也不進行如下步驟。
  • 第三步:若是 valueOf() 方法返回的是對象,就報錯。
String(obj1)     // "[object Object]"
String(obj2)     // "6"
String(obj3)     // "6"

因此,由於 正則,Date,function 等引用類型數據有本身的 toString() 方法,所以返回的都是對應的字符串類型。

Boolean()

Boolean() 函數能夠將任意類型的值轉爲布爾值。

它的轉換規則相對簡單:除了如下個值的轉換結果爲 false 外,其餘的值所有爲 true,包括 [] 空數組或 {} 空對象。

  • false
  • undefined
  • null
  • 0(包含 -0+0
  • NaN
  • ''(空字符串)
Boolean(0)                   // false
Boolean(NaN)                 // false
Boolean({})                  // true
Boolean([])                  // true
Boolean(new Boolean(false))  // true

parseInt(string[, radix]) 、Number.parseInt(string[, radix])

這兩個方法具備同樣的功能。ES6 添加 Number.parseInt() 的目的是對全局變量進行模塊化。

將一個 radix 進制的字符串 string 轉換爲十進制的整數。

  • string:若是參數不是字符串類型,則使用 String()將其轉換爲字符串。
  • radix:介於 2 - 36 之間的數,表明第一個參數 string 的進制數。其默認值會根據狀況變化,若是以 0x 或者 0X 開頭,則默認是 16;以 0 開頭,默認是 8 或者 10 (視環境而定);其他默認是 10。所以,永遠都要明確的給出 radix 參數的值。
  • 返回值:返回值是 string 的十進制整數值。若是 string 的第一個字符沒法被轉化成數值類型,則返回 NaN
parseInt("123", 10);     // 123
parseInt("11", 2);       // 3  二進制數字字符串 ‘11’ 轉換爲十進制的 3

解析規則

  • parseInt() 是逐個解析 stirng 參數中的字符串字符,直到遇到的字符不是正號 +、負號 -、或者科學記數法中的指數 eE 時,且不是 radix 指定的進制中的數字時,就會忽略該字符和後續全部字符,並返回解析到該位置的整數值。
  • 字符串開頭和結尾的空白符將會被忽略;字符串開頭的 0 也會被忽略。
  • 若是 string 的第一個字符不能被轉換成數字,則 parseInt() 返回 NaN
parseInt("15px", 10);   // 15
parseInt("546", 2);     // NaN  除了「0、1」外,其它數字都不是有效二進制數字

parseFloat(string)、Number.parseFloat(string)

這兩個方法具備同樣的功能。ES6 添加 Number.parseFloat() 的目的是對全局變量進行模塊化。

parseFloat() 只應用於解析十進制數字字符串,並返回一個浮點數。

解析規則

  • 若是參數不是字符串類型,則使用 String()將其轉換爲字符串。開頭和結尾的空白符會被忽略。小數點前多餘的 0 也會被忽略。
  • 若是 parseFloat 在解析過程當中遇到了正號 +、負號 -、數字 0-9、小數點 .、或者科學記數法中的指數 eE 之外的字符,則它會忽略該字符以及以後的全部字符,返回當前已經解析到的浮點數。
  • 第二個小數點的出現也會使解析中止。
  • 若是參數字符串的第一個字符不能被解析成爲數字,則返回 NaN
  • parseFloat 也能夠解析並返回 Infinity
parseFloat("10.2abc")   // 10.2

Object()

Object() 函數用來將任意值轉爲對象。

  • 當參數爲原始類型時,會轉換爲對應的包裝對象的實例,
  • 參數爲空或者 undefined 或者 null 時,返回一個空對象。
  • 參數爲引用數據類型時,老是返回其自己,不作轉換。
Object(null)                 // {}

let numObj = Object(1);
numObj instanceof Object    // true
numObj instanceof Number    // true

let arr = [];
Object(arr)=== arr;         // true  返回原數組

隱式轉換

隱式轉換都是以強制轉換爲基礎的。

== 比較

在進行 == 比較的時候,根據兩邊數據類型不一樣,會進行不一樣的數據轉換。

參考 JavaScript 的相等比較

不一樣類型的數據互相運算

+ 法運算

加法運算,當一個值爲字符串,另外一個值爲非字符串時,則經過調用 String() 將非字符串轉爲字符串。

'6' + 1             // '61'
'6' + true          // "6true"
'6' + false         // "6false"
'6' + {}            // "6[object Object]"
'6' + []            // "6"
'6' + function (){} // "6function (){}"
'6' + undefined     // "6undefined"
'6' + null          // "6null"

其它運算符

除了加法運算符(+)有可能把運算子轉爲字符串,其餘運算符都會經過調用 Number() 把運算子自動轉成數值。

'5' - '2'       // 3
'5' * '2'       // 10
true - 1        // 0
false - 1       // -1
'1' - 1         // 0
'5' * []        // 0
false / '5'     // 0
'abc' - 1       // NaN
null + 1        // 1
undefined + 1   // NaN

一元運算符也會把運算子轉成數值

+'abc'    // NaN
-'abc'    // NaN
+true     // 1
-false    // -0  對數值求負

非布爾值類型的數據轉換爲布爾值

JavaScript 遇到預期爲布爾值的地方(好比 if 語句的條件部分),就會將非布爾值的參數自動轉換爲布爾值。系統內部會自動調用 Boolean() 函數。

所以除了 undefinednull0(包含 -0+0)、NaN''(空字符串)五個值爲 false 外,其餘都是自動轉爲 true

三元運算符和取反操做也會將一個值轉爲布爾值。它們內部調用的也是 Boolean() 函數。

// 三元運算符  Boolean({})
({}) ? true : false  //  true

// 兩次取反就是將一個值轉爲布爾值的簡便寫法。等同於 Boolean([])
!![]                 // true
相關文章
相關標籤/搜索