for...of 循环在 JS 是不可或缺

更新日期: 2020-02-24阅读: 1.8k标签: 循环

请教大家一个问题:什么特性让该编程语言更加优秀?

个人见解:当该特性可以组合多个其他语言特性时。

JavaScript 中的for...of语句就是这种情况,可从ES2015开始使用。

for...of可以迭代数组,类似数组的对象以及通常所有可迭代的对象(map,set,dom集合)。

接下我们通过事例来看看 for...of 一些有用的地方。


1. 数组的迭代

for...of的最常见应用是对数组项进行迭代。 该循环可以很好且短暂地完成它,而无需其他变量来保持索引。

例如:

const products = ['橘子', '苹果']

for (const product of products.entries()) {
  console.log(product)
}
// "橘子"
// "苹果"

for...of循环遍历products,迭代的每项值分配给变量product。

数组方法 entries() 可以用于访问迭代项的索引,该方法在每次迭代时返回一组键值对[index, item]。

const products = ['橘子', '苹果']

for (const [index, product] of products.entries()) {
  console.log(index, product)
}
// 0 "橘子"
// 1 "苹果"

在每次迭代中,products.entries()返回一对索引和值,它们由const [index,product]表达式解构。

1.1 就地解构

首先,让我们看一下 for...of 循环的语法

for (LeftHandSideExpression of Expression) {
  // statements
}

LeftHandSideExpression表达式可以替换为赋值表达式左侧的任何内容。

在上面的例子中,LeftHandSideExpression是一个变量声明 const products,也可以是一个解构表达式 const [index, product]。

接着,我们遍历一系列对象,提取每个对象的属性name :

const persons = [
  { name: '前端web' },
  { name: '王大冶' }
]

for (const { name } of persons) {
  console.log(name)
}

// 前端web
// 王大冶

循环for (const { name } of persons) 遍历person数组的对象,同时也就地解构( {name}) person对象的 name 属性值。


2. 类似数组遍历

for...of 除了可以遍历对象外,还可以遍历类似数组的对象。

arguments是函数体内的特殊变量,表示包含函数的所有参数,arguments 也是一个类似数组对象。例如:

function sum() {
  let sum = 0
  for (const number of arguments) {
    sum += number
  }

  return sum
}

sum(1, 2, 3) // 6


3.可迭代的简要概述

JavaScript中的可迭代对象是什么? 它是一个支持迭代协议的对象。

要检查数据类型是否可迭代,可以配合Symbol.iterator方法。 例如,下面的演示显示了数组是可迭代的:

const array = [1, 2, 3]
const iterator = array[Symbol.iterator]()
iterator.next()  // {value: 1, done: false}

for...of接受可迭代,这很棒,因为这样,我们就可以遍历字符和数据结构(数组,类型化数组,集合,映射)等。


4. 字符串字符的遍历

JavaScript 中的原始类型字符串是可迭代的。因此,我们可以轻松地遍历字符串的字符。

const message = 'hello';

for (const character of message) {
  console.log(character);
}
// 'h'
// 'e'
// 'l'
// 'l'
// 'o'

message包含一个字符串值。 由于message也是可迭代的,因此for...of循环遍历message的字符。


5. Map 与 Set 迭代

Map是一个特殊的对象,它将一个键关联到一个值。键可以是任何基本类型(通常是字符串,但也可以是数字等)

幸运的是,Map也是可迭代的(在键/值对上进行迭代),所以使用for...of可以轻松地在所有键/值对上循环遍历。

const names = new Map()
names.set(1, 'one')
names.set(2, 'two')

for (const [numbe, name] of names) {
  console.log(number, name)
}

// 1 "one"
// 2 "two"

for (const [number, name] of names)在names 键/值对映射上进行迭代。

在每个循环中,迭代器都会返回一个数组[key,value],并使用const [number,name]立即对这对数组进行解构。

同样,以相同的方式可以遍历Set的项:

const colors = new Set(['white', 'blue', 'red', 'white']);

for (color of colors) {
  console.log(color);
}
// 'white'
// 'blue'
// 'red'


6. 遍历普通 JavaScript 对象

遍历普通 JS 对象的属性/值对总是很痛苦的。

通常,我要先使用Object.keys()提取对象键,然后使用forEach()来遍历键数组:

const person = {
  name: '前端web',
  job: '前端分享者'
}

Object.keys(person).forEach(prop => {
  console.log(prop, person[prop])
})

// name 前端web
// job 前端分享者

幸运的是,新的Object.entries() 函数与for...of组合提供了一个不错的选择:

const person = {
  name: '前端web',
  job: '前端分享者'
}

for (const [prop, value] of Object.entries(person)) {
  console.log(prop, value)
}

// name 前端web
// job 前端分享者

Object.entries(person)返回一个键和值元组数组:[['name', 'John Smith'], ['job', 'agent']]。 然后,对于for...of循环,遍历元组,并将每个元组解构const [prop,value]。


7.遍历 DOM 集合

你可能知道在 DOM 中使用htmlCollection是多么令人沮丧。因为HTMLCollection是一个类似数组的对象(而不是一个常规数组),所以我们不能使用常规数组方法。

例如,每个 DOM 元素的children属性都是HTMLCollection。 因此,由于for...of可以在类似数组的对象上进行迭代,因此我们可以轻松地迭代子代:

const children = document.body.children;

for (const child of children) {
  console.log(child); // logs each child of <body>
}

此外,for...of可以遍历NodeList集合(可迭代)。 例如,函数document.querySelectorAll(query)返回一个NodeList。

const allImages = document.querySelectorAll('img');

for (const image of allImages) {
  console.log(image); // log each image in the document
}

如果你想遍历 DOM 中的不同种类的集合,那么for...of语句是一个不错的选择。


8. 性能

在遍历大数组时,for...of的速度可能比 for 要慢:

const a = [/* big array */];
for (let i = 0; i < a.length; i++) {
  console.log(a[i]);
}

在每次迭代中调用迭代器比通过增加索引访问该项目的开销更大。 但是,这种细微差别在使用大型阵列的应用程序中以及性能至关重要的应用程序中非常重要,这种情况很少发生。

原文:https://dmitripavlutin.com/


链接: https://fly63.com/article/detial/8725

跳出 forEach

使用for...in遍历对象时,会遍历原型链上的可枚举属性,这可能会导致一些意想不到的问题。所以你一定收到过这样的建议,使用数组的forEach来代替for...in循环。本文给大家总结了5种在forEach中跳出循环的变通之法

JavaScript循环下的async/await

在进行业务开发的过程中,使用了数组的高级函数map,同时使用了ES6语法async/await,发现在map循环下任务是异步执行的,并不符合预期。Array的循环方法map、forEach、filter、reduce、some、every等是并行迭代,可以理解为async/await的效果是无效的

如何中断forEach循环

在使用for循环的时候可以使用break 或者return语句来结束for循环(return直接结束函数),但是如果使用forEach循环如何跳出循环呢?首先尝试一使用return语句----木有效果

用于JavaScript中的循环和同时循环

如果您需要重复大量的代码数百次,这会变得非常笨拙。而且,它也不是很有用。例如,如果希望它重复X次呢?这就是循环的用武之地。次数通常由变量决定,但也可以由实际数字决定。

Js中循环执行

循环:就是一遍又一遍执行相同或者相似的代码,循环的两个要素:循环体:重复执行的代码;循环条件:控制循环的次数

为啥要放弃for循环?

创建一个新的数组,新的数组中的元素是通过检查指定数组中符合条件的元素;注意:1. filter()不会对空数组进行检测;2. filter()不会改变源是数组;

解决使用Vue-Router出现无限循环问题

我在项目里面用到了的是全局守卫,beforeEach,方便管理 不过遇到了一个问题,就是在beforeEach()中设置好判断条件后出现了无限循环的问题 当时的代码如下:

Node.js事件循环

对于本文中一些知识点任然有些模糊,懵懵懂懂,一直都在学习中,通过学习事件循环也看了一些文献,在其中看到了这一句话:除了你的代码,一切都是同步的,我觉得很有道理,对于理解事件循环很有帮助。

关于for循环中使用setTimeout的四种解决方案

我们先来简单了解一下setTimeout延时器的运行机制。setTimeout会先将回调函数放到等待队列中,等待区域内其他主程序执行完毕后,按时间顺序先进先出执行回调函数。本质上是作用域的问题

Js循环的几种方法

for 常用于循环数组 ,for in 常用来循环对象,不建议循环数组,因为i是字符串 可能会有隐患问题,for in 循环会找到 prototype 上去,所以最好在循环体内加一个判断

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!