[关闭]
@15013890200 2019-04-30T11:10:38.000000Z 字数 1692 阅读 561

js隐式类型转换

js 类型转换


1.先来做几道题吧!

  1. [] == false // true
  2. !![] == true // true
  3. !!'' == false // true
  4. [1] == '1' // true
  5. '' == 0 // true
  6. '' == false // true
  7. [1] == true // true
  8. null == 0 // false
  9. null == '' // false
  10. null == undefined // true
  11. ![] == [] // true
  12. !{} == {} // false

2.解析

2.1 为什么 [] == false

js中规定,如果==中有布尔值,只能转化为数字比较(而不是字符串,因为布尔值转化为字符串就变成'true'和'false')

  1. Number(true) // 1
  2. Number(false) // 0
  3. 所以问题转化为,为什么: [] == 0

2.2 为什么 [] == 0

  • Primitive(原值)和非Primitive比较,需要把非Primitive转换成Primitive才可以。[]是一个对象,因此需要toPrimitive()。(大部分对象最后都是用toString来转换成Primitive)
  • 数组的 toString() 相当于 join(',')
  1. [].toString() // ''
  2. [1].toString() // 1
  3. [1,2,3].toString() // 1,2,3
  4. // 上面提到数组的toString相当于join,那么对象的toString方法呢
  5. {}.toString == '[object Object]' // true,注意第一个object是小写,第二个Object是大写
  6. 所以问题转化为,为什么: '' == 0

2.3 为什么 '' == 0

  • ==号,字符串和数字比较会将字符串转化为数字
  • 字符串转化成数字是用Number(),而不是parseInt()和parseFloat()
  1. Number('') // 0
  2. Number('abc') // NaN
  3. 所以问题转化为, 0 == 0 显然返回true

3. 总结

3.1 比较转化路程

  1. [] == false
  2. [] == 0
  3. '' == 0
  4. 0 == 0

3.2 NaN

  • NaN也是数值类型
  • NaN不能等于自身,否则隐式转化就乱了套了
  • 等式两边出现NaN,则返回结果必然是false

3.3 隐式转换的恶果

  1. [1,2,NaN].indexOf(NaN) // -1
  2. [1,2,NaN].includes(NaN) // true

4. 扩展

4.1 为什么 null == 0 为false

两边类型虽然不同,但是null本身就是Primitive类型值了,所以没法toPrimitive。因此==两边始终无法转化为同类型进行比较,所以返回false。

4.2 为什么 null == undefined

  • null 和 undefined 一样都是Primitive,也不是字符串和数字,转无可能。
  • 但是 JS 专门规定了null == undefined 就是返回true,属于一种专门的特殊情况
  1. // The Abstract Equality Comparison Algorithm
  2. If x is null and y is undefined, return true.
  3. If x is undefined and y is null, return true.

4.3 为什么 !![] == true

  • 因为!![]先计算,它已经是true了
  • !运算符可将变量类型转化为布尔类型,null,undefined,NaN,'',0,false,取反都是true,其余全是false
  1. console.log(!null, !undefined, !NaN, !'', !0, !false) // 皆为true
  2. console.log(![], !{}) // 皆为false

4.4 为什么 ![] == []

  1. // 步骤解析
  2. false == [] // [].toString()
  3. false == ''
  4. 0 == ''
  5. 0 == 0

4.5 为什么 !{} == {} 为false

  1. // 解析
  2. false == {} // {}.toString()
  3. false == '[object Object]' // Number(false)
  4. 0 == '[object Object]' // Number('[object Object'])
  5. 0 == NaN // false

5. 其他

ESLint和其他编程规范会各种限制使用==

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注