indexOf 的 >=0 与 !==-1 问题

在一个项目中,别的同事用到了 indexOf,我一般判断都是写成 >=0,而他写作 !==-1。起初我也没在意,因为 indexOf 本身就是返回 Number 类型,且只能是 -1 0 以及 正整数

问题

但在这个项目中,确稍微有一点点不一样。大致复现方案如下:

1
2
3
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,故 result1true

result2 中,因为不存在 c,最终应该返回 false

但是实际,两个都返回 true

1
2
3
const obj = { a: { b: 'aabbcc' } }
const result1 = obj?.a?.b?.indexOf('b') >= 0
const result2 = obj?.a?.c?.indexOf('b') >= 0

如果换成 >=0 的写法,返回结果如预期,分别是 true false

1
const result2 = obj?.a?.c?.indexOf('b') !== -1

这一行中,由于不存在 c,导致后续逻辑被忽略变成了:

1
const result2 = undefined !== -1 // true

解决

第一种,就是改成 >=0

这种写法,本例算是取巧。

1
2
3
const obj = { a: { b: 'aabbcc' } }
const result1 = obj?.a?.b?.indexOf('b') >= 0 // true
const result2 = obj?.a?.c?.indexOf('b') >= 0 // false

第二种,不用可选链写法

改成最原始的写法,简单明了,就是写起来有些繁琐。

1
2
3
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 本身有强转 )。

第三种,对象层次太深,关键步骤单独处理

如果实在难以用第二种方案,那么可以把最终关键步骤单独处理下。当然使用可选链写法或者使用 lodashget 方法,均可。

1
2
3
const obj = { a: { b: 'aabbcc' } }
const temp = (obj?.a?.c?.d?.e?.f) // undefined
const result2 = temp ? temp.indexOf('b') !== -1 : false // false

–END–