indexOf 的 >=0 与 !==-1 问题
· 阅读需 3 分钟
在一个项目中,别的同事用到了 indexOf
,我一般判断都是写成 >=0
,而他写作 !==-1
。起初我也没在意,因为 indexOf 本身就是返回 Number
类型,且只能是 -1
0
以及 正整数
。
问题
但在这个项目中,确稍微有一点点不一样。大致复现方案如下:
const obj = {a: {b: 'aabbcc'}}
const result1 = obj?.a?.b?.indexOf('b') !== -1
const result2 = obj?.a?.c?.indexOf('b') !== -1
result1
中,因为存在 b
,且 indexOf
返回 2
,故 result1
为 true
。
result2
中,因为不存在 c
,最终应该返回 false
。
但是实际,两个都返回 true
。
const obj = {a: {b: 'aabbcc'}}
const result1 = obj?.a?.b?.indexOf('b') >= 0
const result2 = obj?.a?.c?.indexOf('b') >= 0
如果换成 >=0
的写法,返回结果如预期,分别是 true
false
。
const result2 = obj?.a?.c?.indexOf('b') !== -1
这一行中,由于不存在 c
,导致后续逻辑被忽略变成了:
const result2 = undefined !== -1 // true
解决
第一种,就是改成 >=0
这种写法,本例算是取巧。
const obj = {a: {b: 'aabbcc'}}
const result1 = obj?.a?.b?.indexOf('b') >= 0 // true
const result2 = obj?.a?.c?.indexOf('b') >= 0 // false
第二种,不用可选链写法
改成最原始的写法,简单明了,就是写起来有些繁琐。
const obj = {a: {b: 'aabbcc'}}
const result2 = obj && obj.a && obj.a.c && obj.a.c.indexOf('b') !== -1 // undefined
const boolResult2 = !!result2 // false
返回的就是 undefined
,如果必须使用布尔类型,可以转化下。如果直接放到 if
中,也可以不转( if
本身有强转 )。
第三种,对象层次太深,关键步骤单独处理
如果实在难以用第二种方案,那么可以把最终关键步骤单独处理下。当然使用可选链写法或者使用 lodash
的 get
方法,均可。
const obj = {a: {b: 'aabbcc'}}
const temp = (obj?.a?.c?.d?.e?.f) // undefined
const result2 = temp ? temp.indexOf('b') !== -1 : false // false