「这是我参与2022首次更文挑战的第20天,活动详情查看:2022首次更文挑战」
背景
上次写了一个面试题(面试题: typeof 1/0 等于什么和为什么?)大家的浏览量很高,所以这次我在写一个有趣的面试题。大家可以看看,题目是:5 == [[['5']]],求结果。
类型转换
显式类型转换
1. String() 函数把对象的值转换为字符串。
String(true) // 'true'
String(1) // '1'
String(new Date()) // 'Wed Feb 09 2022 09:35:16 GMT+0800 (中国标准时间)'
String('aa') // 'aa'
String({}) // '[object Object]'
String([1]) // '1'
...
2. Number() 函数把对象的值转换为数字。
Number(true) // 1
Number('123') // 123
Number([1]) // 1
Number(new Date()) // 1644370841178
Number('aa') // NaN
Number({}) // NaN
...
3. Boolean() 函数把对象的值转换为布尔。
Boolean(0) //false
Boolean(1) // true
Boolean("") //false
Boolean(null) //false
Boolean(NaN) //false
Boolean("false") //true
...
显式类型转换总结
| 原始值 | Number | String | Boolean |
|---|---|---|---|
| false | 0 | "false" | false |
| true | 1 | "true" | true |
| 0 | 0 | "0" | false |
| 1 | 1 | "1" | true |
| "0" | 0 | "0" | true |
| NaN | NaN | "NaN" | false |
| Infinity | Infinity | "Infinity" | true |
| "" | 0 | "" | false |
| [ ] | 0 | "" | true |
| [20] | 20 | "20" | true |
| function(){} | NaN | "function(){}" | true |
| {} | NaN | "[object Object]" | true |
| null | 0 | "null" | false |
| undefined | NaN | "undefined" | false |
| Symbol("aa") | err | "Symbol(aa)" | true |
隐式类型转换
js中的数据类型是非常弱的,在使用算数运算符时,运算符两边的数据类型可以是任意的,比如,一个字符串可以和一个数字相加。之所以不同的数据类型之间可以做运算,是因为js引擎在运算之前会悄悄地把他们进行了隐式类型转换。
隐式类型转换例子
console.log([] == []) // false
console.log([] == ![]) // true
console.log([] !== []) // true
console.log(NaN != NaN) // true
console.log(null == undefined) // true
console.log(null === undefined) // false
console.log(1 == true) // true
console.log(null > 0) // false
console.log(true + 1) // 2
console.log(undefined + 1) // NaN
console.log({} + 1) // [object Object]1
console.log([] + {}) // [object Object]
console.log([2,3] + [1,2]) // 2,31,2
解题
在js代码中,当运算符在运算时,如果两边数据类型不统一,电脑就无法计算,这时我们编译器会自动将运算符两边的数据做一个数据类型转换,转成一样的数据类型再计算。
题目:5 == [[['5']]]
因为
==两边的数据类型不一样,所以计算机会把数据转换一下再做比较,因为['5']是数组隐式转换时会调用toString()方法,先把['5']转换成'5',现[[['5']]]有三层最后都会转换成'5',然后变成5 == '5'转换5 === 5, 所以最后答案是true
总结
当进行==比较时候: 先检查两个操作数数据类型,如果相同, 则进行===比较, 如果不同, 则愿意为你进行一次隐式类型转换, 转换成相同类型后再进行比较。
<、 >、 <=、 >=、== 总结
- 如果两个操作值都是数值,则进行数值比较。
- 如果两个操作值都是字符串,则比较字符串对应的字符编码值。
- 如果只有一个操作值是数值,则将另一个操作值转换为数值,进行数值比较。
- 如果一个操作数是对象,则调用
valueOf()方法(如果对象没有valueOf()方法则调用toString()方法),得到的结果按照前面的规则执行比较。 - 如果一个操作值是布尔值,则将其转换为数值,再进行比较。