Skip to content

indexOf 引发的一系列问题

Published: at 09:26 AMSuggest Changes

问题

昨天我 Review 了一个项目的代码,发现里面有这么一个方法

!!~origin.indexOf(target);

感觉很高级,因为没这么写过,就是没有用过 !!~ 这样的写法,在群里发出来后,大家都分享了自己的看法,我收获不小。

群友们表示:这个不算高级,就是傻逼写法。为了避免抽象渗漏

讨论

!!~ 是什么

先实验一下 !!~ 的用法

!!~-1; // false
!!~-2; // true
!!~0; // true
!!~1; // true

这个用法是将 ~-1 转换为 0~-2 转换为 1~0 转换为 -1~1 转换为 0,然后再转换为 falsetrue

里面还有一些按位取反的操作,这里就不展开了,感兴趣的可以自己去了解一下。

https://www.cnblogs.com/minorf/p/13225505.html

抽象渗漏

然后我们查一下抽象渗漏,我去,竟然没查到好点的资料,那就把大佬的截图贴上来吧

var a = 'Hello World';

if (a.indexOf('lo') >= 0) {
  // true
  //找到匹配
}

if (a.indexOf('xo') == -1) {
  // true
  //没有找到匹配
}

// >= 0 和 == -1 这样的写法不是很好,称为“”抽象渗漏“,意思是在代码中暴露了底层的实现细节,这里是指用 -1 作为失败时的返回值,这些细节应该被屏蔽掉。

// 通过~字位反转来完成

if (~a.indexOf('lo')) {
  // true
  //找到匹配
}

if (!~a.indexOf('xo')) {
  // true
  //没有找到匹配
}

includes(x) 和 indexOf(x) >= 0 有什么区别

这个是大佬问的一个面试题,答案我简单总结一下

现在有个问题,[1, 2, 3, NaN, 5],让你找 NaN 的 index,你会怎么找

[1, 2, 3, NaN, 5]
  .findIndex((e) => isNaN(e))
  [(1, 2, 3, NaN, 4, 5, 6)].findIndex(Number.isNaN);

不过要注意,这么调用会有副作用,实例上调用的是 Number.isNaN(1, 0, [1, 2, 3, NaN, 4, 5, 6]) 对于形参只有一个的方法还好,多个的可能被后面的两个实参坑

我问了一个奇怪的问题 [1, 2, 3, NaN, 5, void 0],怎么找 Void 0 的 index

[1, 2, 3, NaN, 5, void 0].findIndex((e) => e === void 0);

群友问 [1, 2, 3, Symbol(4), 5, 6] 怎么获取到 Symbol4 的下标呢

const arr = [1,2,3,Symbol(4)]
arr.findIndex(v => {return typeof v === 'symbol' && v.description == 4})

NaN 为什么不等于 NaN

因为 NaN 是逻辑故障值,任何与 NaN 沾边的数学运算都是 NaNNaN 不等于 NaN 是为了防止数学逻辑伪真,比如 'a' _ 4 === 'b' _ 6 等于 true 的话会有很多逻辑有问题,如果开发者不知道 'a' 和 ‘b’ 的确切值的话,就会出现很多问题,所以 NaN 不等于 NaN 是为了防止数学逻辑伪真

NaN - 1 等于多少,为什么

NaN - 1 等于 NaN,因为 NaN 是逻辑故障值,任何与 NaN 沾边的数学运算都是 NaN

后记

吓得我都不敢面试了


Previous Post
优秀的 JavaScript 前端录制回放库 - rrweb
Next Post
Vue3 父子组件传值及方法调用