头图

foreword

Data traversal is the logic that is often used in our daily development. In addition to the most common for, while, and forEach, iterators also provide data traversal interfaces. Understanding iterators helps us to better process data.

Iterator

Iterator is a new traversal mechanism introduced by ES6. Iterator has two core concepts:

  • Iterator is a unified interface, its role is to make various data structures easily accessible, it is implemented through a method whose key is Symbol.iterator.
  • Iterators are pointers (such as cursors in a database) used to traverse elements of a data structure.

Iteration process

The iterative process is as follows:

  • Create an iterator through Symbol.iterator pointing to the start of the current data structure
  • Then the next method is used to iterate downward to point to the next position. The next method will return the object of the current position. The object contains two attributes, value and done. The value is the value of the current attribute, and done is used to judge whether the traversal is over.
  • The traversal ends when done is true

Let's illustrate with a simple example:

const items = ["zero", "one", "two"]; 
const it = items[Symbol.iterator]();  
it.next(); 
>{value: "zero", done: false} 
it.next(); 
>{value: "one", done: false} 
it.next(); 
>{value: "two", done: false} 
it.next(); 
>{value: undefined, done: true}

In the above example, an array is first created, then an iterator is created by the Symbol.iterator method, and then the next method is continuously called to access the internal items of the array. When the attribute done is true, the access ends.

Iterators are part of the protocol (the rules for using them) for iteration. A key feature of this protocol is that it is sequential: the iterator returns one value at a time. This means that if the iterable data structure is non-linear (such as a tree), iteration will linearize it.

iterable data structure

The following are iterable values:

  • Array
  • String
  • Map
  • Set
  • Dom element (work in progress)

We will use a for...of loop (see for...of loop below) to iterate over the data structure.

Array

Arrays ( Array ) and TypedArrays ( TypedArray ) They are iterable.

for (let item of ["zero", "one", "two"]) {  
    console.log(item); 
} 
// output: 
// zero 
// one 
// two

String

Strings are iterables, they traverse Unicode codes, each code may contain one or two Javascript characters.

for (const c of 'z\uD83D\uDC0A') {
    console.log(c); 
} 
// output: 
// z 
// \uD83D\uDC0A

Map

Maps mainly iterate over their entries, each entry will be encoded as an item of [key, value], entries are iterated in a definite situation, and the order is the same as the order of addition.

const map = new Map(); 
map.set(0, "zero"); 
map.set(1, "one");  
for (let item of map) {  
    console.log(item); 
} 
// output: 
// [0, "zero"] 
// [1, "one"]

Note: WeakMaps are not iterable

Set

Set is iterating over its elements in the same order as they were added

const set = new Set(); 
set.add("zero"); 
set.add("one");  
for (let item of set) {
    console.log(item);
} 
// output: 
// zero 
// one

Note: WeakSets are not iterable

arguments

arguments are currently used less and less in ES6, but are also traversable

function args() {
    for (let item of arguments) {
        console.log(item);
    }
} args("zero", "one"); 
// output: 
// zero 
// one

Ordinary objects are not iterable

Ordinary objects are created from object and are not iterable:

// TypeError 
for (let item of {}) {
    console.log(item); 
}

for...of loop

for...of is a new loop introduced in ES6 that replaces for..in and forEach() and supports the new iteration protocol. It can be used to iterate over regular data types like Array , String , Map and Set and so on.

Iterate over regular data types

Array

const nums = ["zero", "one", "two"];
for (let num of nums) {
    console.log(num); 
} 
// TypedArray 
const typedArray1 = new Int8Array(6); 
typedArray1[0] = 10; 
typedArray1[1] = 11;
for (let item of typedArray1) {
    console.log(item);
}

String

const str = "zero";  
for (let item of str) {
    console.log(item);
}

Map

let myMap = new Map(); 
myMap.set(0, "zero"); 
myMap.set(1, "one"); 
myMap.set(2, "two");  
// 遍历 key 和 value 
for (let [key, value] of myMap) {
    console.log(key + " = " + value);
}
for (let [key, value] of myMap.entries()) {
    console.log(key + " = " + value);
}  
// 只遍历 key 
for (let key of myMap.keys()) {
    console.log(key);
}  
// 只遍历 value 
for (let value of myMap.values()) {
    console.log(value);
}

Set

let mySet = new Set(); 
mySet.add("zero"); 
mySet.add("one"); 
mySet.add("two");  
// 遍历整个 set 
for (let item of mySet) {
    console.log(item);
}  
// 只遍历 key 值 
for (let key of mySet.keys()) {
    console.log(key);
}  
// 只遍历 value 
for (let value of mySet.values()) {
    console.log(value);
}  
// 遍历 key 和 value ,两者会相等 
for (let [key, value] of mySet.entries()) {
    console.log(key + " = " + value);
}

iterable data structure

The operand of of must be iterable, which means it cannot be iterated if it is a normal object. If the data structure is in the form of an array, it can be converted and iterated with the help of the Array.from() method.

const arrayLink = {
    length: 2, 
    0: "zero", 
    1: "one"
}
// 报 TypeError 异常 
for (let item of arrayLink) {
    console.log(item);
}  
// 正常运行 
for (let item of Array.from(arrayLink)) {
    console.log(item);
}
// output: 
// zero 
// one 

let , const and var for for..of

If let and const are used, each iteration will create a new storage space, which ensures that the scope is inside the iteration.

const nums = ["zero", "one", "two"];
for (const num of nums) {
    console.log(num);
} 
// 报 ReferenceError 
console.log(num);

From the above example, we can see that the last sentence will report an exception, because the scope of num is only inside the loop body, and the outside is invalid. With var, this doesn't happen because var acts globally and iterations won't create a new storage space each time.

const nums = ["zero", "one", "two"];
forv (var num of nums) {
    console.log(num);
} 
console.log(num);
// output: two

Summarize

The above are some summaries of iterators, and I hope we can use them flexibly in our usual development.

~

~ This article is over, thanks for reading!

~

Learn interesting knowledge, meet interesting friends, and shape interesting souls!

Hello everyone, I am 16221ff4a2f62c, the king , the author of 〖 Programming Samadhi 〗. My official account is " Programming Samadhi ", welcome to pay attention, I hope you will give more advice!


编程三昧
54 声望10 粉丝

学习有趣的知识,交识有趣的朋友,造就有趣的灵魂!