In-depth explanation of iterators in ECMAScript

In-depth explanation of iterators in ECMAScript

Preface

When many junior front-end developers are moving towards intermediate levels, one of the things they are often asked about in interviews is iterators and generators. In fact, they have used them in development, but they don’t know what they are, or they have some understanding but not in depth. This article will be helpful to these developers and explain the iterator clearly.

Earlier iterations

You must know about iteration. It can be simply understood as a loop. In JavaScript, a counted loop is the simplest one. Example:

for(let i = 0; i < 9; ++i){
	console.log("[ i ]", i);
}

The basis of iteration is the loop, which contains several necessary conditions:

  • The number of iterations can be specified
  • You can specify the operation to be performed at each iteration
  • Each iteration is completed before the next iteration begins
  • The order is pre-defined.

When you need to loop through an array, the iteration is performed on an ordered collection. "Ordered" means that all elements in the array can be traversed in order from the first item to the last item. Because the array has a fixed length, and each item can be obtained by index subscript, that is to say, the entire array can be traversed by index. Example:

const arr = ["a", "b", "c"];

for(let i = 0; i < arr.length; ++i){
	console.log(arr[i]);
}

However, this mode requires knowing in advance what data structure is being used, such as an array. If it is replaced with another data type or a data structure with an implicit order, the order of traversal cannot be determined.

So the forEach() method was added in ES5. Example:

const arr = ["a", "b", "c"];

arr.forEach(item=>{
	console.log(item);
});

This method does not need to use the same array index to traverse and obtain the value of a single item, but it cannot mark when the iteration ends, so it is only applicable to array traversal. To solve these problems, after ES6, JavaScript supports the iterator mode.

Iterator Pattern

The iterator pattern is a very abstract term. It can be understood as objects such as arrays or collections, whose elements are limited, independent and unambiguous. Quoting the explanation from the Little Red Book, that is:

The Iterator pattern (especially in the context of ECMAScript) describes a scheme where some structures can be called "iterables" because they implement the formal Iterable interface and can be consumed by an Iterator.

Iterator Factory Functions

The iterator factory function, Symbol.iterator(), is the default property of most built-in types. It exposes the Iterable interface (iterable protocol), which means that if a data type supports iteration, then the type must support the iterable protocol.

ECMAScript specifies that the default iterator exposed must use "Symbol.iterator" as the key and return a new iterator. The method to check if a default iterator property exists is also simple. Example:

const obj = {};
const arr = ["a", "b", "c"];

console.log(obj[Symbol.iterator]); // underdefined
console.log(arr[Symbol.iterator]); // f values() { [native code] }

console.log(arr[Symbol.iterator]()); // ArrayIterator {}

Of course, we don't need to explicitly call the iterator factory function in actual development. Data types that support the iterable protocol are automatically compatible with any language features that accept iterable objects. For example, when we use loops, for-of, deconstruction, and extension operators, the iterator factory function of the provided iterable object is automatically called in the background to create an iterator.

Iterator Protocol

The iterator protocol stipulates that an iterator is a one-time object. When the iterator factory function is called, a next() method is returned. This method is called for each successful iteration to obtain the value of the next iteration. If it is not called, the current position of the iteration is uncertain.

The next() method returns an object containing the following attributes: done and value. done indicates whether the next() method can be called to obtain the next value, which means whether it is "exhausted". It returns a Boolean value. value indicates the next value of the iterable object. When done is true, value is underfined. When done is false, it will continue to call the next iteration. Example:

// Iterable object let arr = ['foo', 'bar']; // Iterator factory function console.log(arr[Symbol.iterator]); // f values() { [native code] }

// Iterator let iter = arr[Symbol.iterator]();
console.log(iter); // ArrayIterator{}

// Execute iteration console.log(iter.next()); // { done: false, value: 'foo' }
console.log(iter.next()); // { done: false, value: 'bar' }
console.log(iter.next()); // { done: true, value: undefined }

Final Thoughts

With the iterator protocol, you can implement a custom iterator, such as specifying the number of times the iterator can be iterated, or terminating the iteration early.

This is the end of this article about iterators in ECMAScript. For more relevant ECMAScript iterator content, please search for previous articles on 123WORDPRESS.COM or continue to browse the related articles below. I hope everyone will support 123WORDPRESS.COM in the future!

<<:  Diagram of the process of implementing direction proxy through nginx

>>:  How to ensure transaction characteristics of MySQL InnoDB?

Recommend

Methods and steps for deploying GitLab environment based on Docker

Note: It is recommended that the virtual machine ...

Priority analysis of and or queries in MySQL

This may be an issue that is easily overlooked. F...

Detailed analysis of MySQL 8.0 memory consumption

Table of contents 1. innodb_buffer_pool_size 2. i...

Javascript destructuring assignment details

Table of contents 1. Array deconstruction 2. Obje...

JavaScript gets the scroll bar position and slides the page to the anchor point

Preface This article records a problem I encounte...

Detailed explanation of the use of Vue image drag and drop zoom component

The specific usage of the Vue image drag and drop...

MySQL encryption and decryption examples

MySQL encryption and decryption examples Data enc...

Detailed explanation of setting up DNS server in Linux

1. DNS server concept Communication on the Intern...

JavaScript macrotasks and microtasks

Macrotasks and Microtasks JavaScript is a single-...

Vue Router loads different components according to background data

Table of contents Requirements encountered in act...

How to use an image button as a reset form button

When we make a form, we often set a submit button ...

How to set npm to load packages from multiple package sources at the same time

Table of contents 1. Build local storage 2. Creat...

Detailed explanation of Nginx's control over access volume

Purpose Understand the Nginx ngx_http_limit_conn_...