js隐式转换实例分析

为什么 [] == false ?

首先我们知道 [] 和 false 一个是对象, 一个是布尔值, 类型不同, 需要类型转换再做比较

要注意, JS 中规定, 如果 == 中有布尔值, 只能转换为数字, 那为什么不是转换成字符串呢?

因为如果布尔值转换成字符串那就是 ‘true’ 和 ‘false’, 那这种对比就毫无意义了

Number(true)// 1 Number(false)// 0

这也符合我们的常识, 很多语言也是类似的设定, 也就是 Bool 属于一种 Int

所以此问题可以转换成: 为什么 [] == 0?

为什么 [] == 0 ?

我们知道 Primitive(原值)和非 Primitive 比较, 需要把非 Primitive 转换成 Primitive 才可以

[] 是一个对象, 因此需要 toPrimitive()

简单的说, 大部分对象最后都是用 toString() 来转换成 Primitive

你也许会问为啥是用 toString 不是 toNumber 之类的呢? 因为每个对象都有 toString 方法, Object.prototype.toString, 更上层的对象也会重写 toString 方法

继续刨根问底, 为啥每个对象都有 toString 而不是 toNumber 呢?

这就是 JS 对新人友好的地方, JS 的对象都可以打印输出, 自带人性化展示, 在终端上人性化展示, 那当然是用字符串啦, 因此选择用 toString 转换 Primitive 理所因当

我们来看看数组的 toString, 数组的 toString 相当于 join()

[].toString()// '' [1].toString()// '1' [1,2,3,4].toString()// '1,2,3,4'

所以此问题可以转换成: 为什么 ‘’ == 0 ?

为了验证我们的想法, 我们来尝试一些更奇葩的对象和字符串的 == 比较

[1]=='1'// true '[object Object]'=={}// true

({}).toString() 是 [object Object], 所以 ‘[object Object]’ == {} 果然也是 true

为什么 ‘’ == 0 ?

字符串和数字比较会把字符串转换成数字

问题来了, 为什么不是把数字转换成字符串呢? 从设计者的角度可能会这样想

都转成数字能处理的复杂场景更多, 容错性更高!

' 1 '==1.0// true '12.10'==12.1// true

这样对开发者就会很方便

要注意, 字符串转成数字不是用的 parseInt() 或者 parseFloat(), 而是 Number()

Number('')// 0 Number('abc')// NaN

所以此问题可以继续转换成: 为什么 0 == 0? 显然就是返回 true

转换路程

推理到此结束, 我们回顾一下这个比较的转换规程

  1. [] == false

  2. [] == 0

  3. ‘’ == 0

  4. 0 == 0

隐式转换的恶果

NaN 不能等于自身是隐式转换最大的恶果

你可以尝试如下操作

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

有比较的地方, 就会有 NaN 特殊处理, 否则就是不严谨

简单逻辑复杂化, 说的就是你 NaN, 可以说 “隐式转换一时爽”~

为什么 null == 0 是 false 呢 ?

两边类型不同, 是不是也要类型转换呢?

要是能转的话确实要转, 但 null 和数字0本身已经是 Primitive 了, 没有机会再走一遍 toPrimitive(), 因此等号两边始终无法转换成同类型, 只能返回 false

为什么 null == undefined ?

和上面的问题一样, null 和 undefined 都是 Primitive, 而且也不是字符串或者数字, 转无可转

但 JS 专门规定了 null == undefined 就是返回 true, 属于一种专门的特殊情况

为什么 !![] 是 true?

这里面不涉及任何 == 比较, 和上面的题目完全是两类题目, 千万不可搞混

此题直接判断这个值是不是 Falsy(假值) 即可, 只要不是这几个值, 都是 true

Falsy 的值有 0, ‘’, false, NaN, null, undefined

类似的问题 !![] == true, 因为这个表达式先要计算 !![], 它已经是 true 了

为什么 ESLint 中会各种限制使用 ==?

我觉得完全可以理解, == 虽然也是一种便捷的转换, 但并不符合传统语言的习惯, 工程化企业化的项目不想用这种 “黑魔法” 也是一种正确的选择。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值