Home Web Front-end JS Tutorial ES6 iterators and for.of loops (detailed tutorial)

ES6 iterators and for.of loops (detailed tutorial)

Jun 06, 2018 pm 05:34 PM
es6 Iterator

This article mainly introduces the learning summary of ES6 iterator (Iterator) and for.of loop usage. Now I will share it with you and give you a reference.

1. What is an iterator?

The generator concept is available in Java, Python and other languages, and ES6 has also been added to JavaScript. Iterator allows us to avoid the need to initialize the collection and index variables. Instead, we use the next method of the iterator object to return the value of the next item in the collection, which is biased toward programming.

Iterators are objects with special interfaces. Contains a next() method. The call returns an object containing two attributes, namely value and done. Value represents the value of the current position, and done represents whether the iteration is complete. When it is true, calling next is invalid.

Traversing collections in ES5 usually uses a for loop. Arrays also have forEach methods, and objects are for-in. Map and Set are added in ES6, and iterators can handle all collection data in a unified way. Iterator is an interface. As long as your data structure exposes an iterator interface, iteration can be completed. ES6 created a new traversal command for...of loop, and the Iterator interface is mainly used for consumption by for...of.

2. How to use iterators?

1. Default Iterator interface

Data structure As long as the Iterator interface is deployed, we will make this data structure "traversable" ( Iterable). ES6 stipulates that the default Iterator interface is deployed in the Symbol.iterator property of the data structure. In other words, as long as a data structure has Symbol.iterator data, it can be considered "traversable" (iterable).

Native data structure that can be consumed by for...of

  1. Array

  2. Map

  3. Set

  4. String

  5. TypedArray (a generic fixed-length buffer type that allows reading from the buffer Binary data)

  6. The arguments object in the function

  7. NodeList object

can be seen above There is no object (Object) in the native data structure. Why?

That’s because the order of traversal of object properties is uncertain and needs to be specified manually by the developer. In essence, the traverser is a linear process. For any non-linear data structure, deploying the traverser interface is equivalent to deploying a linear transformation.

Do the following processing to make the object available for consumption by for...of:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

// code1

function Obj(value) {

  this.value = value;

  this.next = null;

}

Obj.prototype[Symbol.iterator] = function() {

  var iterator = {

    next: next

  };

  var current = this;

  function next() {

    if (current) {

      var value = current.value;

      current = current.next;

      return {

        done: false,

        value: value

      };

    } else {

      return {

        done: true

      };

    }

  }

  return iterator;

}

var one = new Obj(1);

var two = new Obj(2);

var three = new Obj(3);

one.next = two;

two.next = three;

for (var i of one) {

  console.log(i);

}

// 1

// 2

// 3

Copy after login

2. When the Iterator interface is called

(1) Destructuring assignment

1

2

3

4

5

6

// code2

let set = new Set().add('a').add('b').add('c');

let [x,y] = set;

// x='a'; y='b'

let [first, ...rest] = set;

// first='a'; rest=['b','c'];

Copy after login

(2) Extension operator

1

2

3

4

5

6

7

8

// code3

// 例一

var str = 'hello';

[...str] // ['h','e','l','l','o']

// 例二

let arr = ['b', 'c'];

['a', ...arr, 'd']

// ['a', 'b', 'c', 'd']

Copy after login

(3) Yield* expression in the Generator function (introduced in the next chapter)

1

2

3

4

5

6

7

8

9

10

11

12

13

// code4

let generator = function* () {

yield 1;

yield* [2,3,4];

yield 5;

};

var iterator = generator();

iterator.next() // { value: 1, done: false }

iterator.next() // { value: 2, done: false }

iterator.next() // { value: 3, done: false }

iterator.next() // { value: 4, done: false }

iterator.next() // { value: 5, done: false }

iterator.next() // { value: undefined, done: true }

Copy after login

(4) Others Occasion

  1. for..of

  2. Array.from

  3. Map(), Set( ), WeakMap(), WeakSet()

  4. Promise.all()

  5. ##Promise.race()

3. Advantages of for...of loop

Let’s first look at the disadvantages of the array forEach method:

1

2

3

4

// code5

myArray.forEach(function (value) {

 console.log(value);

});

Copy after login

The problem with this writing method is that, It is impossible to break out of the forEach loop midway, and neither the break command nor the return command takes effect.

Look again, the shortcomings of the object for...in loop:

1

2

3

for (var index in myArray) {

 console.log(myArray[index]);

};

Copy after login

  1. The key name of the array is a number, but the for...in loop is based on Strings as key names, "0", "1", "2", etc.

  2. The for...in loop can not only traverse numeric key names, but also traverse manually added period recommendations, even keys on the prototype chain.

  3. In some cases, the for...in loop session traverses the key names in any order

  4. for...in traversal is mainly for Designed for traversing objects, not suitable for traversing arrays

So, what are the significant advantages of for...of?

  1. Has the same concise syntax as for...in, but does not have the shortcomings of for...in

  2. Different from the forEach method, It can be used with break, continue and return

  3. Provides a unified operation interface for traversing all data structures

  4. 1

    2

    3

    4

    5

    6

    for (var n of fibonacci) {

     if (n > 1000) {

      break;

      console.log(n);

     }

    }

    Copy after login

4, How to use for...of loop for each data type?

(1) Array

for...of loop allows traversing the array to obtain key values

1

2

3

4

5

6

7

var arr = ['a', 'b', 'c', 'd'];

for (let a in arr) {

  console.log(a); // 0 1 2 3

}

for (let a of arr) {

  console.log(a); // a b c d

}

Copy after login

for...of loop calls the traverser interface, array The traverser interface only returns values ​​with numeric indexes

1

2

3

4

5

6

7

8

let arr = [3, 5, 7];

arr.foo = 'hello';

for (let i in arr) {

  console.log(i); // "0", "1", "2", "foo"

}

for (let i of arr) {

  console.log(i); // "3", "5", "7"

}

Copy after login

(2) Map and Set structures

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

var engines = new Set(["Gecko", "Trident", "Webkit", "Webkit"]);

for (var e of engines) {

  console.log(e);

}

// Gecko

// Trident

// Webkit

var es6 = new Map();

es6.set("edition", 6);

es6.set("committee", "TC39");

es6.set("standard", "ECMA-262");

for (var [name, value] of es6) {

  console.log(name + ": " + value);

}

// edition: 6

// committee: TC39

// standard: ECMA-262

Copy after login

As can be seen from the above code, for...of loops through Map and Set When traversing a structure, the order of traversal is based on the order in which each member is added to the data structure. When traversing the Set structure, a value is returned, while when traversing the Map structure, an array is returned, and the two members of the array are the current Map members. The key name and key value.

(3) Array-like object

String

1

2

3

4

5

6

7

8

9

10

11

12

// 普通的字符串遍历

let str = "yuan";

for (let s of str) {

 console.log(s); // y u a n

}

 

// 遍历含有 32位 utf-16字符的字符串

for (let x of 'a\uD83D\uDC0A') {

 console.log(x);

}

// 'a'

// '\uD83D\uDC0A'

Copy after login

DOM NodeList object

1

2

3

4

let paras = document.querySelectorAll("p");

for (let p of paras) {

 p.classList.add("test");

}

Copy after login

arguments object

1

2

3

4

5

6

7

8

function printArgs() {

 for (let x of arguments) {

  console.log(x);

 }

}

printArgs("a", "n");

// "a"

// "n"

Copy after login

No Iterator interface class Array object traversal processing

Borrow Array.from method processing

1

2

3

4

5

6

7

8

9

10

11

12

13

let arrayLike = {

  length: 2,

  0 : 'a',

  1 : 'b'

};

// 报错

for (let x of arrayLike) {

  console.log(x);

}

// 正确

for (let x of Array.from(arrayLike)) {

  console.log(x);

}

Copy after login

(4) Object

For ordinary objects, you cannot directly use for...of traversal, otherwise it will An error is reported. The Iterator interface must be deployed before it can be used. Deploy in the following two ways:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

// 方法一:使用 Object.keys 方法讲对象的键名生成一个数组

for (var key of Object.keys(someObject)) {

 console.log(key + ": " + someObject[key]);

}

 

// 方法二:使用Generator 函数将对象重新包装一下

function * entries(obj) {

  for (let key of Object.keys(obj)) {

    yield[key, obj[key]];

  }

}

for (let[key, value] of entries(obj)) {

  console.log(key, "->", value);

}

// a -> 1

// b -> 2

// c -> 3

Copy after login

三、迭代器应用实例

1、斐波那契数列

下面我们就使用迭代器来自定义自己的一个斐波那契数列组,我们直到斐波那契数列有两个运行前提,第一个前提是初始化的前两个数字为0,1,第二个前提是将来的每一个值都是前两个值的和。这样我们的目标就是每次都迭代输出一个新的值。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

var it = { [Symbol.iterator]() {

    return this

  },

  n1: 0,

  n2: 1,

  next() {

    let temp1 = this.n1,

    temp2 = this.n2;

    [this.n1, this.n2] = [temp2, temp1 + temp2]

    return {

      value: temp1,

      done: false

    }

  }

}

 

for (var i = 0; i < 20; i++) {

  console.log(it.next())

}

 

//

  "value": 0,

  "done": false

} {

  "value": 1,

  "done": false

} {

  "value": 1,

  "done": false

} {

  "value": 2,

  "done": false

} {

  "value": 3,

  "done": false

} {

  "value": 5,

  "done": false

}... {

  "value": 2584,

  "done": false

} {

  "value": 4181,

  "done": false

}

Copy after login

2、任务队列迭代器

我们可以定义一个任务队列,该队列初始化时为空,我们将待处理的任务传递后,传入数据进行处理。这样第一次传递的数据只会被任务1处理,第二次传递的只会被任务2处理… 代码如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

var Task = {

  actions: [],

  [Symbol.iterator]() {

    var steps = this.actions.slice();

    return { [Symbol.iterator]() {

        return this;

      },

      next(...args) {

        if (steps.length > 0) {

          let res = steps.shift()(...args);

          return {

            value: res,

            done: false

          }

        } else {

          return {

            done: true

          }

        }

      }

    }

  }

}

 

Task.actions.push(function task1(...args) {

  console.log("任务一:相乘") return args.reduce(function(x, y) {

    return x * y

  })

},

function task2(...args) {

  console.log("任务二:相加") return args.reduce(function(x, y) {

    return x + y

  }) * 2

},

function task3(...args) {

  console.log("任务三:相减") return args.reduce(function(x, y) {

    return x - y

  })

});

 

var it = Task[Symbol.iterator]();

console.log(it.next(10, 100, 2));

console.log(it.next(20, 50, 100)) console.log(it.next(10, 2, 1))

 //

任务一:相乘 {

  "value": 2000,

  "done": false

}任务二:相加 {

  "value": 340,

  "done": false

}任务三:相减 {

  "value": 7,

  "done": false

}

Copy after login

3、延迟执行

假设我们有一个数据表,我们想按大小顺序依次的获取数据,但是我们又不想提前给他排序,有可能我们根本就不去使用它,所以我们可以在第一次使用的时候再排序,做到延迟执行代码:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

var table = {

  "d": 1,

  "b": 4,

  "c": 12,

  "a": 12

}

table[Symbol.iterator] = function() {

  var _this = this;

  var keys = null;

  var index = 0;

 

  return {

    next: function() {

      if (keys === null) {

        keys = Object.keys(_this).sort();

      }

 

      return {

        value: keys[index],

        done: index++>keys.length

      };

    }

  }

}

 

for (var a of table) {

  console.log(a)

}

// a b c d

Copy after login

上面是我整理给大家的,希望今后会对大家有帮助。

相关文章:

在vue中如何实现微信分享朋友圈,发送朋友

详解如何实现vuex(详细教程)

通过vue.js实现微信支付

The above is the detailed content of ES6 iterators and for.of loops (detailed tutorial). For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

How to use iterators and recursive algorithms to process data in C# How to use iterators and recursive algorithms to process data in C# Oct 08, 2023 pm 07:21 PM

How to use iterators and recursive algorithms to process data in C# requires specific code examples. In C#, iterators and recursive algorithms are two commonly used data processing methods. Iterators can help us traverse the elements in a collection, and recursive algorithms can handle complex problems efficiently. This article details how to use iterators and recursive algorithms to process data, and provides specific code examples. Using Iterators to Process Data In C#, we can use iterators to iterate over the elements in a collection without knowing the size of the collection in advance. Through the iterator, I

Is async for es6 or es7? Is async for es6 or es7? Jan 29, 2023 pm 05:36 PM

async is es7. async and await are new additions to ES7 and are solutions for asynchronous operations; async/await can be said to be syntactic sugar for co modules and generator functions, solving js asynchronous code with clearer semantics. As the name suggests, async means "asynchronous". Async is used to declare that a function is asynchronous; there is a strict rule between async and await. Both cannot be separated from each other, and await can only be written in async functions.

Why does the mini program need to convert es6 to es5? Why does the mini program need to convert es6 to es5? Nov 21, 2022 pm 06:15 PM

For browser compatibility. As a new specification for JS, ES6 adds a lot of new syntax and API. However, modern browsers do not have high support for the new features of ES6, so ES6 code needs to be converted to ES5 code. In the WeChat web developer tools, babel is used by default to convert the developer's ES6 syntax code into ES5 code that is well supported by all three terminals, helping developers solve development problems caused by different environments; only in the project Just configure and check the "ES6 to ES5" option.

How to implement array deduplication in es5 and es6 How to implement array deduplication in es5 and es6 Jan 16, 2023 pm 05:09 PM

In es5, you can use the for statement and indexOf() function to achieve array deduplication. The syntax "for(i=0;i<array length;i++){a=newArr.indexOf(arr[i]);if(a== -1){...}}". In es6, you can use the spread operator, Array.from() and Set to remove duplication; you need to first convert the array into a Set object to remove duplication, and then use the spread operator or the Array.from() function to convert the Set object back to an array. Just group.

What does es6 temporary Zenless Zone Zero mean? What does es6 temporary Zenless Zone Zero mean? Jan 03, 2023 pm 03:56 PM

In es6, the temporary dead zone is a syntax error, which refers to the let and const commands that make the block form a closed scope. Within a code block, before a variable is declared using the let/const command, the variable is unavailable and belongs to the variable's "dead zone" before the variable is declared; this is syntactically called a "temporary dead zone". ES6 stipulates that variable promotion does not occur in temporary dead zones and let and const statements, mainly to reduce runtime errors and prevent the variable from being used before it is declared, resulting in unexpected behavior.

Detailed explanation of implementation and use of Golang iterator Detailed explanation of implementation and use of Golang iterator Mar 17, 2024 pm 09:21 PM

Golang is a fast and efficient statically compiled language. Its concise syntax and powerful performance make it very popular in the field of software development. In Golang, iterator (Iterator) is a commonly used design pattern for traversing elements in a collection without exposing the internal structure of the collection. This article will introduce in detail how to implement and use iterators in Golang, and help readers better understand through specific code examples. 1. Definition of iterator In Golang, iterator usually consists of an interface and implementation

Best practices for iterators in PHP programs Best practices for iterators in PHP programs Jun 06, 2023 am 08:05 AM

Best Practices for Iterators in PHP Programs Iterator is a very common design pattern in PHP programming. By implementing the iterator interface, we can traverse the elements in a collection object, and we can also easily implement our own iterator object. In PHP, the iterator pattern can help us operate collection objects such as arrays and lists more efficiently. In this article, we will introduce the best practices for iterators in PHP programs, hoping to help PHP developers who are also working on iterator applications. 1. Use the standard iterator interface P

How to use the next() function in Python to get the next element of an iterator How to use the next() function in Python to get the next element of an iterator Aug 22, 2023 pm 04:40 PM

How to use the next() function in Python to get the next element of an iterator. Iterator is a very commonly used concept in Python, which allows us to traverse a data collection in a specific order. During the iteration process, we often need to obtain the next element of the iterator. In this case, we can use the next() function to achieve this. In Python, we can use the iter() function to convert an iterable object into an iterator. For example, if we have a list, we can convert it into an iterator

See all articles