JS中的類型轉換

七種數據類型

JS 中共有七種數據類型javascript

  • null
  • undefined
  • boolean
  • number
  • string
  • symbol
  • object

除了 object,全部的數據類型都被稱爲「原始數據類型」html

JS 中每一個變量都保存了一個值,每一個值都對應着一種數據類型java

在使用過程當中,值的數據類型會發生相應的變化,以促使代碼正常運行git

顯示轉換

Number()

typeof new Number('a') // "object"
typeof Number('a') // "number"

給 Number() 函數傳遞任何參數,都會返回一個 number 類型的值github

Number() 在轉換原始數據類型時函數

Number(324) // 324
// 數值類型,直接返回
Number('324') // 324
// 字符串能夠轉成數字,就將其轉成數字返回
Number('324abc') // NaN
// 字符串不可轉成數字,返回 NaN
Number('') // 0
// 空字符串,返回 0
Number(true) // 1
// true,返回 1
Number(false) // 0
// false,返回 0
Number(undefined) // NaN
// undefined,返回 NaN
Number(null) // 0
// null,返回 0

值得一提的是 parseInt() 也能夠將參數轉化爲數值code

parseInt('324abc') // 123
parseInt('abc324') // NaN
parseInt('') // NaN
parseInt(true) // NaN
parseInt(false) // NaN
parseInt(undefined) // NaN
parseInt(null) // NaN

Number() 在轉換對象時htm

僞代碼以下對象

Number(obj)
if(Type obj.valueOf() is Primitive) return Number(obj.valueOf())
else(Type obj.toString() is Primitive) return Number(obj.toString())
else TypeError
let obj = {
    valueOf(){
        return 110
    },
    toString(){
        return 120
    }
}
Number(obj) // 110

let obj2 = {
    valueOf(){
        return []
    },
    toString(){
        return 120
    }
}
Number(obj2) // 120

Number([])ip

  1. [].valueOf() 返回 [],非原始數據類型
  2. [].toString() 返回 "",爲原始數據類型,空字符串
  3. Number('') 返回 0

Number({})

  1. ({}).valueOf() 返回 {},非原始數據類型
  2. ({}).toString() 返回 "[object object]",爲原始數據類型,字符串
  3. Number("[object object]"),字符串不可轉換爲數值,返回 NaN

String()

typeof new String(123) // "object"
typeof String(123) // "string"

給 String() 函數傳遞任何參數,都會返回一個 string 類型的值

String() 在轉換原始數據類型時

String('abc') // "abc"
// 字符串類型直接返回
String(123) // "123"
// 數值類型轉換爲相應的字符串
String(true) // "true"
String(false) // "false"
String(undefined) // "undefined"
String(null) // "null"

String() 在轉換對象時

其轉換原理與 Number() 轉換對象的原理相似,只不過 Number() 先調用對象的 valueOf() 方法進行判斷,失敗後,再調用對象的 toString() 方法。String() 則是先調用對象的 toString() 方法進行判斷,失敗後,再調用對象的 valueOf() 方法

let obj = {
    valueOf(){
        return '110'
    },
    toString(){
        return '120'
    }
}
String(obj) // "120"

let obj2 = {
    valueOf(){
        return "120"
    },
    toString(){
        return {}
    }
}
String(obj2) // "120"
String([]) // ""
String({}) // "[object Object]"

Boolean()

typeof new Boolean(123) // "object"
typeof Boolean(123) // boolean

Boolean() 返回 false 的狀況不多

Boolean(undefined) // false
Boolean(null) // false
Boolean(0) // false
Boolean(+0) // false
Boolean(-0) // false
Boolean(NaN) // false
Boolean('') // false

除此以外,皆爲 true

Boolean({}) // true
Boolean([]) // true
Boolean(new Boolean(false)) // true

隱式轉換

自動轉換爲boolean

JS 遇到預期爲 boolean 時,會內部調用 Boolean()

  • if (conditions) => if (Boolean(conditions))
  • while (conditions) => while (Boolean(conditions))
  • expr1 && expr2 => Boolean(expr1) && Boolean(expr2)
  • expr1 || expr2 => Boolean(expr1) || Boolean(expr2)
  • ! expr1 => ! Boolean(expr1)
  • condition ? value1 : value2 => Boolean(condition) ? value1 : value2

自動轉換爲string

在字符串的加法運算時, a + b,若 a 爲字符串,b 不爲字符串,則發生 a + String(b)

'5' + 1 // '51'
'5' + true // "5true"
'5' + false // "5false"
'5' + {} // "5[object Object]"
'5' + [] // "5"
'5' + function (){} // "5function (){}"
'5' + undefined // "5undefined"
'5' + null // "5null"
let obj2 = {
    valueOf(){
        return "120"
    },
    toString(){
        return {}
    }
}
'5' + obj2 // 5120
let obj = {
    width: 100
}
'5' + obj.width // 5100

自動轉換爲number

在使用算術運算符時,會調用 Number(),使算子都變成 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

當 + 以二元運算符使用,且算子中有一個爲字符串時,看成拼接字符串使用

當 + 以二元運算符使用,且算子中有一個爲對象時,看成拼接字符串使用

[1,2] + [2,3] // "1,22,3"
[] + {} // "[object object]"
{} + [] // 0
// {} 被看成塊級做用域處理
// + 被看成一元運算符
// 調用 Number([])
({}) + [] // "[object object]"

詳解兩類隱式轉換

x == y

  1. 若是 x,y 的類型相同,則返回 x == y
  2. 若是 x 爲 undefined,y 爲 null,或者, x 爲 null,y 爲 undefined,都返回 true
  3. 若是 x,y 都爲基礎數據類型,但類型不一樣,返回 Number(x) == Number(y)
  4. 若是一者爲基礎數據類型,一者爲對象,則返回 ToPrimitive(obj) == primitive

ToPrimitive(obj),先調用 obj.valueOf(),判斷是不是基礎數據類型,若不是,則調用 obj.toString()

[] == ![] => [] == !Boolean([]) => [] == !true => [] == false => "" == false => true

console.log(([][[]]+[])[+!![]]+([]+{})[!+[]+!![]])

1.([][[]]+[])

([][[]]+[]) => ([][""]+[]) => (undefined + []) => ("undefined")

2.[+!![]]

[+!![]] => [+!!Boolean([])] => [+!!true] => [+true] => [+1] => [1]

那麼 ([][[]]+[])[+!![]] => ("undefined")[1] => "n"

3.([]+{})

([]+{}) => ("[object object]")

4.[!+[]+!![]]

[!+[]+!![]] => [!+[]+true] => [!+"" + true] => [!+0+true] => [!0+true] => [1+true] => [2]

那麼 ([]+{})[!+[]+!![]] => ("[object object]")[2] => "b"

綜上

console.log(([][[]]+[])[+!![]]+([]+{})[!+[]+!![]]) // nb

參考資料

相關文章
相關標籤/搜索