JS 中共有七種數據類型javascript
除了 object,全部的數據類型都被稱爲「原始數據類型」html
JS 中每一個變量都保存了一個值,每一個值都對應着一種數據類型java
在使用過程當中,值的數據類型會發生相應的變化,以促使代碼正常運行git
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
[].valueOf()
返回 []
,非原始數據類型[].toString()
返回 ""
,爲原始數據類型,空字符串Number('')
返回 0
Number({})
({}).valueOf()
返回 {}
,非原始數據類型({}).toString()
返回 "[object object]"
,爲原始數據類型,字符串Number("[object object]")
,字符串不可轉換爲數值,返回 NaN
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]"
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
JS 遇到預期爲 boolean 時,會內部調用 Boolean()
在字符串的加法運算時, 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
算術運算符有
'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]"
ToPrimitive(obj),先調用 obj.valueOf(),判斷是不是基礎數據類型,若不是,則調用 obj.toString()
[] == ![] => [] == !Boolean([]) => [] == !true => [] == false => "" == false => true
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