这是 ES2016 的两个小升级,都是"让代码更短更直白":includes 像直接问导购"这排货架里有没有这款",当场答有/没有;** 就是数学里的"几次方"符号,2 的 10 次方直接写 2 ** 10,不用再调 Math.pow。
indexOf 是"告诉你它在第几号货架",找不到就报 -1,你还得自己判断一下;includes 是直接答"有/没有"。
let arr = [1, 2, 3, 4, 5]; // 一排货架,5 件商品 // 以前:indexOf 找不到返回 -1,还得 !== -1 转成布尔 console.log(arr.indexOf(1) !== -1); // true // 现在:includes 直接给 true / false console.log(arr.includes(1)); // true(有) console.log(arr.includes(9)); // false(没有)
indexOf 内部用 === 比较,而 NaN 是个"谁都不认识它"的怪东西,NaN === NaN 居然是 false。includes 用的是另一套比较规则,能认出 NaN。
console.log([NaN].indexOf(NaN)); // -1(找不到!因为 NaN !== NaN) console.log([NaN].includes(NaN)); // true(includes 能认出来)
如果你要判断数组里有没有 NaN,还用 indexOf,就会一直以为没有——因为 NaN 自己都不等于自己。换成 includes 就正常了。这是两者最大的行为差异。
数学课本里"几次方"就一个小上标,JS 以前得调 Math.pow 函数,现在直接用两个星号 **。
// 以前:调用函数 console.log(Math.pow(2, 10)); // 1024 console.log(Math.pow(3, 3)); // 27 // 现在:** 就是乘方 console.log(2 ** 10); // 1024 console.log(3 ** 3); // 27
console.log(2 ** 0.5); // 1.414...(0.5 次方就是开根号) console.log(2 ** -1); // 0.5(负次方是倒数) let x = 3; // 先放个数 x **= 2; // 等价于 x = x ** 2,自己平方自己 console.log(x); // 9
**= 和 +=、-= 是一个套路——"自己等于自己做一次运算",比如 x += 1 是加一,x **= 2 就是平方。
① 可能在什么地方用:判断菜单/权限里有没有某项、购物车是否含某商品、做幂等/分页计算(2 ** page)、判断值是否在白名单里。
② 常见的问题:用 indexOf !== -1 判断 NaN 永远 false;把 ** 写成 ^(^ 在 JS 里是异或,不是乘方);和 Math.pow 混用导致阅读混乱。
③ 解决思路:判存在一律用 includes(含 NaN);乘方用 **,别用 ^;老代码里看到 Math.pow(a, b) 可放心等价替换成 a ** b。