七种数据类型
JS 中共有七种数据类型
- null
- undefined
- boolean
- number
- string
- symbol
- object
除了 object,所有的数据类型都被称为“原始数据类型”
JS 中每个变量都保存了一个值,每个值都对应着一种数据类型
在使用过程中,值的数据类型会发生相应的变化,以促使代码正常运行
显示转换
Number()
typeof new Number('a') // "object"
typeof Number('a') // "number"
给 Number() 函数传递任何参数,都会返回一个 number 类型的值
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() 也可以将参数转化为数值
parseInt('324abc') // 123
parseInt('abc324') // NaN
parseInt('') // NaN
parseInt(true) // NaN
parseInt(false) // NaN
parseInt(undefined) // NaN
parseInt(null) // NaN
Number() 在转换对象时
伪代码如下
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([])
-
[].valueOf()
返回[]
,非原始数据类型 -
[].toString()
返回""
,为原始数据类型,空字符串 -
Number('')
返回0
Number({})
-
({}).valueOf()
返回{}
,非原始数据类型 -
({}).toString()
返回"[object object]"
,为原始数据类型,字符串 -
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
- 如果 x,y 的类型相同,则返回 x == y
- 如果 x 为 undefined,y 为 null,或者, x 为 null,y 为 undefined,都返回 true
- 如果 x,y 都为基础数据类型,但类型不同,返回 Number(x) == Number(y)
- 如果一者为基础数据类型,一者为对象,则返回 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
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。