Boolean()将其他数据类型转成布尔值
- 0、-0、空字符串""、null、undefined、NaN、false、document.all()这8个转布尔值为false,其他的都为true。
Boolean(0) // false
Boolean(-0) // false
Boolean(‘‘) // false
Boolean(null) // false
Boolean(undefined) // false
Boolean(NaN) // false
Boolean(document.all()) // false
Boolean(‘ ‘) // true
Boolean(‘-1‘) // true
Boolean([]) // true
Boolean({}) // true
Boolean(function(){}) // true
Boolean(Symbol()) // true
Number()将其他数据类型转成数值
- null转为0
- undefined转为NaN
- true转为1,false转为0
- 引用类型先转成字符串然后再转成数值,字符串必须是数字字符串才能成功转成相应的数值,否则都为NaN。空字符串""以及只有空格的字符串" "转为0
Number(null) // 0
Number(undefined) // NaN
Number(true) // 1
Number(false) // 0
Number(‘‘) // 0
Number(‘ ‘) // 0
Number([1]) // 1 [1].toString()返回‘1‘
Number([1,2]) // NaN [1,2].toString()返回‘1,2‘,转数值为NaN
Number({}) // NaN ({}).toString()返回‘[object Object]‘,转数值为NaN
注:事实上引用类型转数值的过程中会自动调用对象的 valueOf() 和 toString()。
- 先调用 valueOf(),返回值是基本类型的话,即可转数值。
- 如果 valueOf() 的返回值不可直接转数值的话,再自动调用对象的toString(),然后再将得到的字符串转数值。
var obj = {
valueOf: function(){
console.log(‘valueOf方法被调用了‘);
return ‘666‘;
},
toString: function(){
console.log(‘toString方法被调用了‘);
return ‘2333‘;
}
}
Number(obj)
// valueOf方法被调用了
// 666
var obj = {
valueOf: function(){
console.log(‘valueOf方法被调用了‘);
return {};
},
toString: function(){
console.log(‘toString方法被调用了‘);
return ‘2333‘;
}
}
Number(obj)
// valueOf方法被调用了
// toString方法被调用了
// 2333
valueOf() 返回对象的原始值
MDN文档
valueOf方法一般都会被 JavaScript 自动调用,比如发生隐形转换时。
String()将其他数据类型转成字符串
String() 和 toString() 效果基本相同,唯一区别就是toString()无法转换null和undefined
var a;
var b=null;
a.toString(); //Uncaught TypeError: Cannot read property ‘toString‘ of undefined
b.toString(); //Uncaught TypeError: Cannot read property ‘toString‘ of null
String(a); //"undefined"
String(b); //"null"
注:引用类型隐形转换字符串时还是遵循先 valueOf() 再 toString(),而不是直接 String()
var obj = {
valueOf: function(){
console.log(‘valueOf方法被调用了‘);
return ‘666‘;
},
toString: function(){
console.log(‘toString方法被调用了‘);
return ‘2333‘;
}
}
‘00-‘ + obj
// valueOf方法被调用了
// ‘00-666‘
‘00-‘ + String(obj)
// toString方法被调用了
// ‘00-2333‘
隐式类型转换场景
+ (字符串连接符/算术运算符)
+两边有一边是字符串的话,此时+为字符串连接符,其他情况则为算术运算符。
- 字符串连接符:将其他数据类型转成字符串,然后进行拼接。
- 算术运算符:将其他数据类型用Number()转成数字,然后做加法运算。
1 + ‘-haha‘ // ‘1-haha‘
1 + true // 2 Number(true)为1
1 + null // 1 Number(null)为0
1 + undefined // NaN Number(undefined)为NaN
1 + {} // ‘1[object Object]‘ {}转数字的过程中先转成了字符串,然后就变成了字符串拼接
1 + [1,2,3] // ‘11,2,3‘ 原因同上
[] + {} // ‘[object Object]‘ 原因同上
{} + [] // 0 大括号{}在前面被认为是代码块,所以相当于是 +[]
>、<、>=、<= (关系运算符)
会把其他数据类型转成number数字类型来进行比较,但有些具体情况比较特殊。
- >、<、>=、<= 的两边都是字符串的话,比较的是字符的Unicode编码。
// 一般情况下 Number(‘2‘) > 10 false
‘2‘ > 10 // false
// 两边都是字符串 ‘2‘.charCodeAt() > ‘10‘.charCodeAt() true
‘2‘ > ‘10‘ // true
// 多个字符依次比较 ‘a‘.charCodeAt() > ‘b‘.charCodeAt false
‘aac‘ > ‘abc‘ // false
<br/>
## ==(关系运算符)
* 类型相同,不发生类型转换。如果都是引用类型,则比较的是引用地址
* 类型不同,则转成number数字类型再进行比较
* NaN不与任何值相等,包括NaN自己
```javascript
[1] == [1] // false
{} == {} // false
9 == [9] // true
NaN == NaN // false
特殊情况:如果数据类型是 null 和 undefined ,结果固定,无规则。
null == null // true
undefined == undefined // true
undefined == null // true
!(逻辑非)
- 逻辑非,将其他数据类型转成布尔值
- 逻辑非!优先级高于关系运算符
// 先算逻辑非,Boolean([])为true => ![]为false => Number(false)为0
![] == 0 // true
// 先算逻辑非,![]为false => Number(false)为0,[].toString()为‘‘ => Number(‘‘)为0
[] == ![] // true
// 先算逻辑非,({}).toString()为‘[object Object]‘ => Boolean(‘[object Object]‘) => !{}为false,Number(‘[object Object]‘)为NaN
{} == !{} // false
经典面试题
var a = ???
if(a == 1 && a == 2 && a == 3){
console.log(‘少林功夫好嘢‘);
}
// 如何完善a,使其正确打印出‘少林功夫好嘢‘
// 分析
// ==会发生隐式转换
// ==两边数据类型不同则转成Number数字类型来进行比较
// a比较3次3次不同,a只能是引用类型,引用类型转Number数字类型过程先后自动调用valueOf()和toString()
// 经过以上几步分析,豁然开朗
var a = {
b: 1,
valueOf: function(){
return this.b++;
}
}
if(a == 1 && a == 2 && a == 3){
console.log(‘少林功夫好嘢‘)
}
// ‘少林功夫好嘢‘