了解JavaScript for ... of循环

什么是For ... of循环? ( What is the For...of Loop? )

The for...of statement creates a loop that iterates over iterable objects. For...of loop was introduced in ES6 to be an alternative to both for..in and forEach() and supports the new iteration protocol. For..of lets you loop over data structures that are iterable such as Arrays, strings, Maps, Sets, and more.

for...of语句创建一个循环,循环访问可迭代对象。 ES6中引入了For...of循环,以替代for..inforEach( ),并支持新的迭代协议。 For..of可让您遍历可迭代的数据结构,例如数组,字符串,映射,集合等。

句法 (Syntax)

for (variable of iterable) {
  statement
}
  • variable - For every iteration the value of the property is assigned to the the variable.

    变量-对于每次迭代,将属性的值分配给变量。
  • iterable - An object which has enumerable properties and can be iterated upon.

    可迭代-具有可枚举属性并且可以对其进行迭代的对象。

用例 ( Use Cases )

Let's explore some use cases.

让我们探索一些用例。

数组 (Arrays)

Arrays are simply list-like objects. Array prototype has various methods that allow operations to be performed on it such as mutation and traversing operations. Here's a for...of operation on an array:

数组只是类似于列表的对象。 数组原型具有多种允许对其执行操作的方法,例如变异和遍历操作。 这是对数组的for...of操作:

// array-example.js
const iterable = ['mini', 'mani', 'mo'];

for (const value of iterable) {
  console.log(value);
}

// Output:
// mini
// mani
// mo

The result is a print-out of every value in the iterable array.

结果是iterable数组中每个值的打印输出。

Demo: https://jsbin.com/dimahag/edit?js,console

演示: https : //jsbin.com/dimahag/edit?js,console

地图 (Map)

The Map object holds key-value pairs. Objects and primitive values can be used as either a key or a value. A Map object iterates through elements based on how it was inserted. In order words, for...of loop returns an array of key-value pair for each iteration.

Map对象包含键值对。 对象和原始值可以用作键或值。 Map对象根据其插入方式遍历元素。 用顺序来说, for...of循环为每次迭代返回键-值对数组。

// map-example.js
const iterable = new Map([['one', 1], ['two', 2]]);

for (const [key, value] of iterable) {
  console.log(`Key: ${key} and Value: ${value}`);
}

// Output:
// Key: one and Value: 1
// Key: two and Value: 2

Demo: https://jsbin.com/lofewiw/edit?js,console

演示: https : //jsbin.com/lofewiw/edit?js,console

(Set)

The Set object allows you store unique values of any type, which could be primitive values or objects. Set objects are simply collections of values. Iteration on the elements of a Set is based on insertion order. A value in the Set may only occur once. In order words, if you create a set that has the same element more than once, it is still considered as a single element.

Set对象允许您存储任何类型的唯一值,这些值可以是原始值或对象。 集合对象只是值的集合。 Set元素上的迭代基于插入顺序。 集合中的值只能出现一次。 用命令的话来说,如果您创建一个具有多个相同元素的集合,则仍将其视为单个元素。

// set-example.js
const iterable = new Set([1, 1, 2, 2, 1]);

for (const value of iterable) {
  console.log(value);
}
// Output:
// 1
// 2

Even though we have a set that has multiple 1's and 2's, we have the output as just 1 and 2.

即使我们有一个包含多个1和2的集合,我们的输出也只有1和2。

Demo: https://jsbin.com/fajozob/edit?js,console

演示: https : //jsbin.com/fajozob/edit?js,控制台

(String)

Strings are used to store data in text form.

字符串用于以文本形式存储数据。

// string-example.js
const iterable = 'javascript';

for (const value of iterable) {
  console.log(value);
}

// Output:
// "j"
// "a"
// "v"
// "a"
// "s"
// "c"
// "r"
// "i"
// "p"
// "t"

Here, iteration in performed on a string and the character on each index is printed out.

在此,对字符串执行迭代,并打印出每个索引上的字符。

Demo: https://jsbin.com/rixakeg/edit?js,console

演示: https : //jsbin.com/rixakeg/edit?js,控制台

参数对象 (Arguments Object)

Think of an argument's object simply as an Array-like object corresponding to the arguments passed to a function. Here's a use case:

将参数的对象简单地视为与传递给函数的参数相对应的类似于数组的对象。 这是一个用例:

// arguments-example.js
function args() {
  for (const arg of arguments) {
    console.log(arg);
  }
}

args('a', 'b', 'c');
// Output:
// a
// b
// c

You might be wondering, what is going on?! As I said earlier on, arguments recieves any argument passed into the args() function when the function is called. So, if we pass 20 arguments to the args() function, we have 20 arguments printed out.

您可能想知道,这是怎么回事? 就像我之前说过的,当调用函数时, arguments接收传递给args()函数的任何参数。 因此,如果将20个参数传递给args()函数,则将输出20个参数。

Demo: https://jsbin.com/ciqabov/edit?js,console

演示: https : //jsbin.com/ciqabov/edit?js,控制台

发电机 (Generators)

Generators are functions which can be exited and later re-entered.

生成器是可以退出并随后重新输入的函数。

// generator-example.js
function* generator(){ 
  yield 1; 
  yield 2; 
  yield 3; 
}; 

for (const g of generator()) { 
  console.log(g); 
}

// Output:
// 1
// 2
// 3

The function* defines a generator function, which returns a Generator object. For more on Generators, check here.

function*定义了一个生成器函数,该函数返回一个生成器对象。 有关发生器的更多信息,请在此处检查。

Demo: https://jsbin.com/faviyi/edit?js,console

演示: https : //jsbin.com/faviyi/edit?js,console

关闭迭代器 ( Closing Iterators )

JavaScript offers four known methods of terminating a loop execution namely: break, continue, return and throw. Let's look at an example:

JavaScript提供了四种终止循环执行的已知方法,即: breakcontinuereturnthrow 。 让我们看一个例子:

const iterable = ['mini', 'mani', 'mo'];

for (const value of iterable) {
  console.log(value);
  break;
}

// Output:
// mini

In this example, we use the break keyword to terminate the loop after one execution and only mini gets printed out.

在此示例中,我们使用break关键字在执行一次后终止循环,并且仅打印出mini

Demo: https://jsbin.com/tisuken/edit?js,console

演示: https : //jsbin.com/tisuken/edit?js,console

普通对象是不可迭代的 ( Plain objects are not iterable )

For...of loop only works with iterables. Plain objects are not iterable. Let's have a look:

For...of循环仅适用于可迭代对象。 普通对象是不可迭代的。 我们来看一下:

const obj = { fname: 'foo', lname: 'bar' };

for (const value of obj) { // TypeError: obj[Symbol.iterator] is not a function
    console.log(value);
}

Here we define a plain object obj and when we try the for...of operation on it, we get an error TypeError: obj[Symbol.iterator] is not a function.

在这里,我们定义了一个普通对象obj ,当我们尝试对其for...of操作时,会收到错误TypeError: obj[Symbol.iterator] is not a function

Demo: https://jsbin.com/sotidu/edit?js,console

演示: https : //jsbin.com/sotidu/edit?js,console

We can by-pass this by converting an array-like object to an Array. The object would have a length property and its element would have to be indexed. Let's look at an example:

我们可以通过将类似数组的对象转换为Array来绕过它。 该对象将具有length属性,并且其元素必须被索引。 让我们看一个例子:

// object-example.js
const obj = { length: 3, 0: 'foo', 1: 'bar', 2: 'baz' };

const array = Array.from(obj);
for (const value of array) { 
    console.log(value);
}
// Output:
// foo
// bar
// baz

The Array.from() method creates a new Array instance from an array-like or iterable object.

Array.from()方法从类似于数组或可迭代的对象中创建一个新的Array实例。

Demo: https://jsbin.com/miwofin/edit?js,console

演示: https : //jsbin.com/miwofin/edit?js,控制台

对于...对...对于...在 ( For...of vs For...in )

The for...in loop will iterate over all enumerable properties of an object.

for...in循环将遍历对象的所有可枚举属性。

//for-in-example.js
Array.prototype.newArr = () => {};
Array.prototype.anotherNewArr = () => {};
const array = ['foo', 'bar', 'baz'];

for (const value in array) { 
  console.log(value);
}
// Outcome:
// 0
// 1
// 2
// newArr
// anotherNewArr

For...in doesn't only enumerate the array declaration above, it also looks for inherited non-enumerable properties from the constructor's prototype, in this case newArr and anotherNewArr and prints them out also.

For...in不仅枚举上面的数组声明,还从构造函数的原型中查找继承的不可枚举的属性,在这种情况下为newArranotherNewArr并打印出来。

Demo: https://jsbin.com/quxojof/edit?js,console

演示: https : //jsbin.com/quxojof/edit?js,控制台

For...of is more specific to collections such as arrays and object but doesn't include all objects.

For...of更特定于集合,例如数组和对象,但不包括所有对象。

Note: Any element that has the Symbol.iterator property is iterable.

注意:任何具有Symbol.iterator属性的元素都是可迭代的。

Array.prototype.newArr = () => {};
const array = ['foo', 'bar', 'baz'];

for (const value of array) { 
  console.log(value);
}
// Outcome:
// foo
// bar
// baz

For...of doesn't considered non-enumerable properties of the constructor's prototype. It simply just looks for the enumerable properties and prints it out.

For...of不认为构造函数原型的不可枚举的属性。 它只是寻找可枚举的属性并将其打印出来。

Demo: https://jsbin.com/sakado/edit?js,console

演示: https : //jsbin.com/sakado/edit?js,console

摘要 ( Summary )

Understanding the usage of For...of loop can save you a lot of time during development. Hopefully this article helped you understand and write better loop constructs in your JavaScript development. Happy coding!

了解For...of循环的用法可以在开发过程中节省大量时间。 希望本文能帮助您了解和编写JavaScript开发中更好的循环结构。 编码愉快!

翻译自: https://scotch.io/tutorials/understanding-the-javascript-forof-loop

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值