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