ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

core-js 相对索引方法(Relative Indexing Method)完整指南:Array / String / TypedArray 的 `.at()` 负索引读取

core-js 相对索引方法(Relative Indexing Method)完整指南:Array / String / TypedArray 的 `.at()` 负索引读取 core-js 相对索引方法Relative Indexing Method完整指南Array / String / TypedArray 的.at()负索引读取【免费下载链接】core-jsStandard Library项目地址: https://gitcode.com/GitHub_Trending/co/core-js导读相对索引方法Relative Indexing Method是 TC39 提出的 ECMAScript 提案为Array、String和%TypedArray%引入统一的at(index)方法允许通过负索引从末尾读取元素终结了arr[arr.length - 1]这类冗长写法的历史。本指南以 docs/web/docs/features/proposals/relative-indexing-method.md 为骨架结合 core-js 仓库中es.array.at、es.string.at-alternative、es.typed-array.at三个模块的源码与单元测试讲解该提案在 core-js 中的实现原理、内置方法签名、入口使用方式及边界行为。读完你将掌握.at()的完整语义、core-js 的 polyfill 加载入口以及如何用单元测试验证 polyfill 的兼容行为。提案背景与 core-js 中的定位相对索引方法Relative Indexing Method的规范与提案仓库分别见 tc39 规范 与 提案仓库。它解决的核心痛点在于传统下标arr[-1]在 JavaScript 中返回undefined开发者只能写arr[arr.length - 1]来取末位元素可读性差且容易出错。.at()让负索引从末尾倒数语义直观且统一。在 core-js 中该提案当前处于 Stage 4已进入 ES2022 正式规范因此它同时出现在core-js/proposals入口对应提案入口与core-js/stage入口对应Stage 4 集合中在 packages/core-js/stage/4.js 中可以看到require(../proposals/relative-indexing-method)的引入语句由于已入标准Array.prototype.at、String.prototype.at、%TypedArray%.prototype.at也都以es.*前缀标准模块形式存在于 packages/core-js/modules 目录。从源码结构看core-js 对已进 Stage 4 的提案采用了双入口策略既保留proposals/入口方便按提案名精确引入也纳入stage/集合统一引入最终随着正式版发布迁移为es.*标准模块。内置方法签名Built-ins signatures文档给出了三种内置对象的at方法签名核心语义一致class Array { at(index: int): any; } class String { at(index: int): string; } class %TypedArray% { at(index: int): number; }三个方法的参数都是整数index返回值类型分别为any数组元素、string字符串字符和number类型化数组元素。签名背后的统一算法如下将this强制转换为可索引对象Object / String / TypedArray取得其长度len将index经ToIntegerOrInfinity抽象操作转换为整数relativeIndex若relativeIndex 0则k relativeIndex否则k len relativeIndex负索引从末尾倒数若k 0 || k len返回undefined否则返回O[k]。这一算法在三份实现中几乎逐行一致下面结合源码逐一分析。源码级实现三个at模块的异同1.Array.prototype.at— packages/core-js/modules/es.array.at.js$({ target: Array, proto: true }, { at: function at(index) { var O toObject(this); var len lengthOfArrayLike(O); var relativeIndex toIntegerOrInfinity(index); var k relativeIndex 0 ? relativeIndex : len relativeIndex; return (k 0 || k len) ? undefined : O[k]; } }); addToUnscopables(at);关键点toObject(this)将this包装为对象保证at.call({ 0: 1, length: 1 }, 0)这类类数组对象调用也能工作lengthOfArrayLike(O)读取对象的length兼容类数组toIntegerOrInfinity(index)把参数转成整数见下文内部抽象操作addToUnscopables(at)将at加入Array.prototype[Symbol.unscopables]避免with (arr) { at }这类历史遗留语法被新方法污染。2.String.prototype.at— packages/core-js/modules/es.string.at-alternative.jsvar charAt uncurryThis(.charAt); var FORCED fails(function () { return .at(-2) ! \uD842; }); $({ target: String, proto: true, forced: FORCED }, { at: function at(index) { var S toString(requireObjectCoercible(this)); var len S.length; var relativeIndex toIntegerOrInfinity(index); var k relativeIndex 0 ? relativeIndex : len relativeIndex; return (k 0 || k len) ? undefined : charAt(S, k); } });与数组版本的区别forced: FORCED特性探测通过fails检测运行环境自带的String.prototype.at是否符合规范——检测用例是.at(-2) ! \uD842。是占两个 UTF-16 码元surrogate pair的字符at(-2)规范上应返回第一个码元\uD842。如果宿主实现按码点而非码元取字符返回说明实现有误core-js 就会强制覆盖为自身 polyfilluncurryThis(.charAt)以非包装方式借用原生charAt避免在String子类或代理对象上产生额外开销返回越界时同样是undefined与数组行为对齐。3.%TypedArray%.prototype.at— packages/core-js/modules/es.typed-array.at.jsexportTypedArrayMethod(at, function at(index) { var O aTypedArray(this); var len lengthOfArrayLike(O); var relativeIndex toIntegerOrInfinity(index); var k relativeIndex 0 ? relativeIndex : len relativeIndex; return (k 0 || k len) ? undefined : O[k]; });该模块通过ArrayBufferViewCore.exportTypedArrayMethod一次性为所有类型化数组子类Int8Array、Uint16Array、Float64Array等 9 种视图注册at方法并用aTypedArray(this)做类型强校验确保只作用于真正的 TypedArray 实例。返回的仍是number类型的元素值越界返回undefined。补充在proposals入口中TypedArray 部分目前通过 packages/core-js/modules/esnext.typed-array.at.js 间接引用es.typed-array.at文件头部有// TODO: Remove from core-js4注释说明该入口属于提案时代的遗留转发标准实现始终是es.typed-array.at。内部抽象操作toIntegerOrInfinity与参数规范化三份实现都调用了 packages/core-js/internals/to-integer-or-infinity.jsvar trunc require(../internals/math-trunc); module.exports function (argument) { var number argument; return number ! number || number 0 ? 0 : trunc(number); };该内部模块实现规范中的ToIntegerOrInfinity抽象操作行为要点先把参数一元取正argument转成 numberNaN与±0统一归零number ! number || number 0 ? 0其余值用Math.trunc截断小数部分。由此推导出.at()的几个实用边界行为均可由 tests/unit-global/es.array.at.js 中的断言证实[1, 2, 3].at(NaN)→1NaN 归 0即取第一个元素[1].at()→1无参数时undefined转 NaN同样归 0[1, 2, 3].at(-0)→1-0 0成立按正索引 0 处理[1, 2, 3].at(0.4)/at(0.5)/at(0.6)→ 均为1小数被截断为 0。边界行为与测试验证core-js 的单元测试 tests/unit-global/es.array.at.js 使用 QUnit 对Array#at做了系统验证几乎逐条覆盖上文算法assert.same([1, 2, 3].at(0), 1); assert.same([1, 2, 3].at(3), undefined); // 越界返回 undefined assert.same([1, 2, 3].at(-1), 3); // 负索引从末尾倒数 assert.same([1, 2, 3].at(-4), undefined); // 负索引越界 assert.same([1, 2, 3].at(0.4), 1); // 小数截断 assert.same([1].at(NaN), 1); assert.same([1].at(), 1); assert.same([1, 2, 3].at(-0), 1); assert.same(Array(1).at(0), undefined); // 稀疏空位返回 undefined assert.same(at.call({ 0: 1, length: 1 }, 0), 1); // 类数组对象可用 assert.true(at in Array.prototype[Symbol.unscopables]); // unscopables 注册严格模式下还断言了对null/undefined调用会抛TypeError。归纳出的行为规则如下调用形式结果说明arr.at(i)i 0且i lenarr[i]正索引按位取arr.at(-1)末位元素len - 1arr.at(-len)首位元素恰好倒数到 0arr.at(i)i len或i -lenundefined越界不抛错arr.at(0.5)/arr.at(NaN)/arr.at()等价于arr.at(0)参数被ToIntegerOrInfinity规范化at.call(null)/at.call(undefined)TypeError严格模式下不可索引对String#at和%TypedArray%#at的越界行为完全一致返回undefined不抛异常也不改变原对象。Entry points如何在项目中引入文档给出的提案入口为core-js/proposals/relative-indexing-method在代码中使用时对应import core-js/proposals/relative-indexing-method; // 或 CommonJS require(core-js/proposals/relative-indexing-method);该入口文件 packages/core-js/proposals/relative-indexing-method.js 的实现非常简洁本质是三个模块的聚合转发use strict; // https://github.com/tc39/proposal-relative-indexing-method require(../modules/es.string.at-alternative); require(../modules/esnext.array.at); require(../modules/esnext.typed-array.at);由于该提案已经进入 ES2022 正式规范core-js 还提供了多种等价或更细粒度的引入方式可按需选择按模块细粒度引入体积最小core-js/es/array/at、core-js/es/string/at、core-js/es/typed-array/at分别对应标准模块 es.array.at.js、es.string.at-alternative.js、es.typed-array.at.js按类别引入core-js/es/array、core-js/es/string、core-js/es/typed-array按 Stage 引入core-js/stage或core-js/stage/4其中 packages/core-js/stage/4.js 已包含require(../proposals/relative-indexing-method)全量引入core-js完整 polyfill或core-js/stable仅标准特性已包含.at()。关于入口语义的完整说明可参阅仓库文档 docs/web/docs/usage 中的 Entry points 小节。选用建议若只依赖.at()一个特性且在意包体积直接用core-js/es/array/at等三个细粒度入口若项目已统一按core-js/stable全量引入则无需额外引入。与其他取元素方式的对比方式取末位元素越界行为备注arr[arr.length - 1]繁琐返回undefined需先取length可读性差arr.slice(-1)[0]需再解包返回undefined产生新数组有分配开销arr.at(-1)直接、直观返回undefined提案语义不产生新对象在类型化数组上typedArray.at(-1)同样避免了typedArray[typedArray.length - 1]的样板代码而String.prototype.at(-1)则省去了str[str.length - 1]。这就是相对索引方法统一三类的意义一份直觉负索引倒数三种内置类型通用。小结相对索引方法为Array、String、%TypedArray%提供统一的at(index)方法负索引从末尾倒数越界返回undefined参数经由ToIntegerOrInfinity规范化NaN、±0 归零小数截断core-js 的三份实现共享同一套核心算法String#at额外通过forced特性探测修正不规范的宿主实现该提案已是 Stage 4ES2022可按core-js/proposals/relative-indexing-method提案入口、core-js/es/*/at标准模块入口或core-js/stage集合入口引入实现与边界行为均有源码es.array.at.js、es.string.at-alternative.js、es.typed-array.at.js与单元测试tests/unit-global/es.array.at.js双重背书可在引入前按上表行为表自行验证运行环境的兼容性。【免费下载链接】core-jsStandard Library项目地址: https://gitcode.com/GitHub_Trending/co/core-js创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表