当前位置: 首页
前端开发
如何用 Array.prototype.entries 配合 for...of 在遍历数组的同时获取索引和值

如何用 Array.prototype.entries 配合 for...of 在遍历数组的同时获取索引和值

热心网友 时间:2026-04-24
转载

如何用 Array.prototype.entries 配合 for...of 在遍历数组的同时获取索引和值

如何用 Array.prototype.entries 配合 for...of 在遍历数组的同时获取索引和值

entries() 返回的是什么类型的迭代器

先说清楚一个核心概念:Array.prototype.entries() 返回的,是一个标准的数组迭代器对象。这意味着,每次调用它的 next() 方法,产出的都是一个长度为 2 的数组,格式固定为 [索引, 值]

这里有个常见的“坑”:它产出的不是对象,也不是 Map 或 Set 结构。所以,如果你试图直接用对象解构的语法,比如写成 { index, value } 去接收,代码肯定会报错——这正是很多开发者初次使用时感到困惑的地方。

好在,当我们使用 for...of 循环时,引擎会自动帮我们处理迭代器的 next() 调用。我们只需要关注:如何优雅地拆开每次循环得到的那个二元数组。

for...of 中正确解构 entries() 的写法

答案很明确:必须使用数组解构语法,并且顺序是固定的——第一个位置放索引,第二个位置放值。

下面是一些典型的对比例子:

  • 正确写法for (const [i, v] of arr.entries()) { ... }。一步到位,清晰简洁。
  • 错误写法for (const {index, value} of arr.entries()) { ... }。如前所述,entries() 不产出对象,此路不通。
  • ⚠️ 低效写法for (const entry of arr.entries()) { const [i, v] = entry; ... }。虽然功能上能达到目的,但多了一次声明和赋值,显得冗余。

来看一个具体的例子,感受一下它的简洁:

const arr = ['a', 'b', 'c'];
for (const [i, v] of arr.entries()) {
  console.log(i, v); // 依次输出:0 'a' → 1 'b' → 2 'c'
}

和 for...in、传统 for 循环比有什么区别

这是个好问题。选择哪种遍历方式,很大程度上取决于你想避开哪些“坑”。

for...in 循环设计初衷是遍历对象的可枚举属性,用在数组上时,它会把索引当作字符串来遍历,更麻烦的是,它可能会遍历到数组原型链上后来添加的属性,或者数组对象本身的非数字属性。这通常不是我们想要的结果。

传统的 for (let i = 0; i < arr.length; i++) 循环当然很强大,一切尽在掌控。但代价是,你需要手动维护索引变量 i,小心处理边界条件。此外,它在迭代器语义层面(比如与某些可迭代协议的配合)不如 for...of 直接。

那么 arr.entries() 配合 for...of 的优势在哪?

  • 精准:它只产出数组自身、按顺序排列的索引-值对,不会有多余的“杂质”。
  • 稳定:即使是稀疏数组(有空位),它也会为每个位置产出对应的索引(值表现为 empty)。
  • 灵活:它返回的迭代器可以被多次消费(只要没耗尽),而 for...of 每次循环都会使用一个新的迭代。

至于性能,在绝大多数现代应用场景中,它与传统 for 循环的差异微乎其微,完全可以忽略。如果一段代码的性能瓶颈真的卡在循环方式上,那更值得审视的,恐怕是循环体内的业务逻辑本身。

遇到空位或 undefined 元素时的行为

这是 Ja vaScript 数组一个比较微妙的点:“空位”(hole)和显式存入的 undefined 值,在底层是不同的。entries() 方法对两者的处理也有区别。

  • 对于空位数组(如 const a = [, , 3];),entries() 会产出:[0, empty], [1, empty], [2, 3]。注意,这里的 empty 表示值真正缺失,并非 undefined
  • 对于显式包含 undefined 的数组(如 const b = [undefined, undefined, 3];),产出则是:[0, undefined], [1, undefined], [2, 3]

for...of 循环中解构时,空位(empty)位置解构出来的 v 也会是 undefined。这就导致了一个问题:你无法通过简单的 v === undefined 来判断,这个位置到底是空位,还是确实存了一个 undefined 值。

如果需要精确区分,就得借助 arr.hasOwnProperty(i) 或者 ES2022 引入的 Object.hasOwn(arr, i) 方法来判断该索引是否为数组的自有属性。

最后,值得再次强调:entries() 是 Array 原型上的方法,它主要服务于标准的 Ja vaScript 数组。对于 TypedArray、类数组对象(如 arguments)或者 NodeList 等,通常需要先将其转换为真正的数组(例如使用 Array.from() 或扩展运算符 ...),或者采用其他更适合的方式来获取索引和值。

来源:https://www.php.cn/faq/2334655.html

游乐网为非赢利性网站,所展示的游戏/软件/文章内容均来自于互联网或第三方用户上传分享,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系youleyoucom@outlook.com。

同类文章
更多
checked表单属性与CSS变量实现换肤原理

checked表单属性与CSS变量实现换肤原理

先聊一个有意思的现象:不需要编写任何 JavaScript,仅靠一个 :checked 伪类,就能驱动整个主题切换系统。听起来很神奇,但原理其实并不复杂——核心在于,:checked 是浏览器原生状态的实时镜像,而不是 JS 模拟出来的开关。 用户点击 ,或者用键盘空格键选中它,状态更新的那一刻,C

时间:2026-07-02 06:55
HTML meta标签页面定时跳转实现

HTML meta标签页面定时跳转实现

说到前端开发中最简洁的页面跳转方式,meta http-equiv= "refresh " 绝对算得上一个经典方案。不过别看它结构简单,格式上稍有疏忽,页面就可能原地卡死,或者直接跳到一个错误地址。下面把几个最容易踩坑的细节彻底讲清楚,帮你避开这些常见陷阱。 使用 http-equiv= "refresh

时间:2026-07-02 06:54
Cypress跨测试用例状态传递的不推荐但可选方案

Cypress跨测试用例状态传递的不推荐但可选方案

Cypress 默认的设计哲学很干脆:每个测试用例都必须是独立小王国,谁也不靠谁。这意味着 it() 执行前,浏览器上下文会被“一键还原”——页面状态、LocalStorage、Cookies 统统清空,强制维护测试隔离。这一规则让很多新手头疼:明明前一个测试已经创建了员工,后一个测试怎么就没法直接

时间:2026-07-02 06:54
全面深度解析HTML主体main标签唯一性原则与使用规范

全面深度解析HTML主体main标签唯一性原则与使用规范

在进行前端无障碍审计时,不少开发者会遇到一个奇怪的场景:浏览器不报错,但Lighthouse却直接标红“duplicate-main”。这其实是语义层与渲染层之间的根本差异。 为什么浏览器不报错但 Lighthouse 直接标红 duplicate-main 关键原因就在于:`main` 是语义锚点

时间:2026-07-02 06:54
HTML main标签在文档结构中的唯一性详解

HTML main标签在文档结构中的唯一性详解

先做一个快速检测:打开你最近开发的一个页面,按下 Ctrl+F 搜索 。如果搜索结果里出现2个以上,那这篇文章建议你认真读完。 本期要聊的主题,是HTML标签中一个看似简单、实际极易踩坑的核心知识点:main标签的唯一性。很多开发者知道这个标签的存在,但真正写到项目里,尤其是用了React、Vue这

时间:2026-07-02 06:54
热门专题
更多
刀塔传奇破解版无限钻石下载大全 刀塔传奇破解版无限钻石下载大全
洛克王国正式正版手游下载安装大全 洛克王国正式正版手游下载安装大全
思美人手游下载专区 思美人手游下载专区
好玩的阿拉德之怒游戏下载合集 好玩的阿拉德之怒游戏下载合集
不思议迷宫手游下载合集 不思议迷宫手游下载合集
百宝袋汉化组游戏最新合集 百宝袋汉化组游戏最新合集
jsk游戏合集30款游戏大全 jsk游戏合集30款游戏大全
宾果消消消原版下载大全 宾果消消消原版下载大全
  • 日榜
  • 周榜
  • 月榜