@15013890200
2019-04-30T11:10:38.000000Z
字数 1692
阅读 561
js
类型转换
[] == false // true
!![] == true // true
!!'' == false // true
[1] == '1' // true
'' == 0 // true
'' == false // true
[1] == true // true
null == 0 // false
null == '' // false
null == undefined // true
![] == [] // true
!{} == {} // false
js中规定,如果
==
中有布尔值
,只能转化为数字
比较(而不是字符串,因为布尔值转化为字符串就变成'true'和'false')
Number(true) // 1
Number(false) // 0
所以问题转化为,为什么: [] == 0
- Primitive(原值)和非Primitive比较,需要把非Primitive转换成Primitive才可以。[]是一个对象,因此需要toPrimitive()。(大部分对象最后都是用toString来转换成Primitive)
- 数组的 toString() 相当于 join(',')
[].toString() // ''
[1].toString() // 1
[1,2,3].toString() // 1,2,3
// 上面提到数组的toString相当于join,那么对象的toString方法呢
{}.toString == '[object Object]' // true,注意第一个object是小写,第二个Object是大写
所以问题转化为,为什么: '' == 0
- ==号,字符串和数字比较会将字符串转化为数字
- 字符串转化成数字是用Number(),而不是parseInt()和parseFloat()
Number('') // 0
Number('abc') // NaN
所以问题转化为, 0 == 0 显然返回true
[] == false
[] == 0
'' == 0
0 == 0
- NaN也是数值类型
- NaN不能等于自身,否则隐式转化就乱了套了
- 等式两边出现NaN,则返回结果必然是false
[1,2,NaN].indexOf(NaN) // -1
[1,2,NaN].includes(NaN) // true
两边类型虽然不同,但是null本身就是Primitive类型值了,所以没法toPrimitive。因此==两边始终无法转化为同类型进行比较,所以返回false。
- null 和 undefined 一样都是Primitive,也不是字符串和数字,转无可能。
- 但是 JS 专门规定了null == undefined 就是返回true,属于一种专门的特殊情况
// The Abstract Equality Comparison Algorithm
If x is null and y is undefined, return true.
If x is undefined and y is null, return true.
- 因为!![]先计算,它已经是true了
- !运算符可将变量类型转化为布尔类型,null,undefined,NaN,'',0,false,取反都是true,其余全是false
console.log(!null, !undefined, !NaN, !'', !0, !false) // 皆为true
console.log(![], !{}) // 皆为false
// 步骤解析
false == [] // [].toString()
false == ''
0 == ''
0 == 0
// 解析
false == {} // {}.toString()
false == '[object Object]' // Number(false)
0 == '[object Object]' // Number('[object Object'])
0 == NaN // false
ESLint和其他编程规范会各种限制使用==