Array.includes兼容实现中o.length>>>0与fromIndex|0的作用及原因
解读Array.includes Polyfill中的
len = o.length >>> 0和n = fromIndex | 0 嘿,这个问题问到点子上了!这两行代码其实是在严格对齐ECMAScript规范,把JavaScript里各种“不按常理出牌”的变量值,转换成Array.includes方法要求的标准数值。咱们拆开一个个说:
第一行:var len = o.length >>> 0;
这行的核心作用是把目标对象(数组或类数组)的length属性,转换成一个合法的非负整数,对应规范里的ToLength操作。
为啥用无符号右移>>> 0这种看起来有点奇怪的写法?
- JavaScript里的
length属性其实没那么“规矩”——理论上它可以是负数、字符串、甚至undefined,但includes必须基于一个有效的非负长度来遍历元素。 >>> 0是个小巧高效的技巧:它会把任何输入值转换成32位无符号整数。比如:- 正数小数会被截断:
3.9 >>> 0→3 - 负数会被转成对应的无符号32位值(虽然规范里
ToLength会把负数转成0,但这个值在后续遍历里不会触发循环,相当于间接实现了规范要求) - 非数字值(比如字符串
"10"、undefined)会被转成0
- 正数小数会被截断:
- 比起用
Math.max(0, Math.min(parseInt(o.length), 2**53-1))这种直白写法,位运算的执行速度更快,代码也更简洁。
第二行:var n = fromIndex | 0;
这行是把fromIndex参数转换成一个32位有符号整数,对应规范里的ToInteger操作,同时完美处理了“如果fromIndex未定义,默认从0开始”的要求。
用按位或| 0的原因也很实在:
| 0会强制把任何值转换成32位有符号整数:小数直接截断(2.5 | 0→2)、负数保留符号(-3.8 | 0→-3)、undefined或NaN会被转成0——正好符合规范里“未传fromIndex时默认用0”的规则。- 它比
parseInt或者Number()更贴合规范的ToInteger逻辑:比如parseInt("123abc")会返回123,但规范里ToInteger("123abc")会先转成NaN再变成0,"123abc" | 0也会返回0,完全对齐规范。 - 同样,位运算的性能比普通类型转换要高不少。
总的来说,这两行都是用JS位运算的特性,快速、精准地模拟规范要求的类型转换,既保证polyfill的行为和原生Array.includes完全一致,又兼顾了代码的执行效率。
内容的提问来源于stack exchange,提问作者tzortzik
相关产品推荐
相关产品推荐

