Javascript 简明教程

JavaScript - User Defined Iterators

在 JavaScript 中,iterable 是一个在其对象原型中有 Symbol.iterator() 方法的对象。可迭代对象的一些示例包括数组、集合、映射、字符串等。Symbol.iterator() 方法返回一个对象,其中包含 iterator 调用的 next() 方法。此处,next() 方法在每次调用时返回可迭代对象的元素。

In JavaScript, an iterable is an object which has Symbol.iterator() method in the object prototype. Some examples of iterable are array, set, map, string, etc. The Symbol.iterator() method returns an object containing the next() method is called iterator. Here, the next() method returns the elements of iterable in each call.

The next() Method

迭代器对象的 next() 方法返回一个包含下面给出的两个键值对的对象。

The next() method of the iterator object returns an object containing two key-value pairs given below.

  1. value − The value key contains the element as a value.

  2. done − The done key contains the boolean value. It contains true if all iterations of iterable are finished. Otherwise, it contains false.

Example

在下面的示例中,我们创建了数组并将数组迭代器存储在“iter”变量中。然后,我们使用迭代器对象的 next() 方法获取下一个值。

In the example below, we have created the array and stored the array iterator in the 'iter' variable. After that, we use the next() method of the iterator object to get the next value.

输出显示 next() 方法返回包含“value”和“done”属性的对象。最后一次迭代仅返回包含“done”属性的对象。

The output shows that the next() method returns the object containing 'value' and 'done' properties. The last iteration returns the object containing the 'done' property only.

<html>
<head>
   <title> JavaScript - Iterators </title>
</head>
<body>
   <p id = "output"> </p>
   <script>
      const output = document.getElementById("output");
      const nums = [10, 72, 45];
      const iter = nums[Symbol.iterator]();
      output.innerHTML += JSON.stringify(iter.next()) + "<br>";
      output.innerHTML += JSON.stringify(iter.next()) + "<br>";
      output.innerHTML += JSON.stringify(iter.next()) + "<br>";
      output.innerHTML += JSON.stringify(iter.next()) + "<br>";
   </script>
</body>
</html>
{"value":10,"done":false}
{"value":72,"done":false}
{"value":45,"done":false}
{"done":true}

User-defined Iterators

在上面部分,我们了解了迭代器在 JavaScript 中的工作原理。Symbol.iterator() 方法返回包含 next() 方法的对象,并且每当我们执行 next() 方法时,它都会返回一个对象。

In the above part, we have looked at how an iterator works in JavaScript. The Symbol.iterator() method returns the object containing the next() method, and whenever we execute the next() method, it returns an object.

因此,以同样的方式,我们可以实现用户定义的迭代器。

So, in the same way, we can implement the user-defined iterators.

Example

在下面的示例中,我们使用函数创建了自定义迭代器。该函数返回包含 next() 方法的对象。next() 方法返回包含数组元素和 nth 索引处 false 布尔值的对象,如果 n 小于数组长度。如果 n 大于或等于数组长度,它返回仅包含“done”属性(布尔值为“true”)的对象。

In the example below, we have created the custom iterator using the function. The function returns the object containing the next() method. The next() method returns the object containing the array element and the false boolean value from the nth index if n is less than the array length. If the n is greater than or equal to the array’s length, it returns the object containing only the 'done' property with a 'true' boolean value.

然后,我们使用 iter.next() 语法获取下一个数组元素。

After that, we use the iter.next() syntax to get the next array element.

<html>
<head>
   <title> JavaScript - User defined iterators </title>
</head>
<body>
   <p id = "output"> </p>
   <script>
      const output = document.getElementById("output");
      function customIterator(chars) {
         // To track index
         let n = 0;
         return {
            // next() method
            next() {
               if (n < chars.length) {
                  return {
                     value: chars[n++],
                     done: false
                  }
               }
               return {
                  done: true
               }
            }
         }
      }
      const chars = ['A', 'C', 'E'];
      const iter = customIterator(chars);
      output.innerHTML += JSON.stringify(iter.next()) + "<br>";
      output.innerHTML += JSON.stringify(iter.next()) + "<br>";
      output.innerHTML += JSON.stringify(iter.next()) + "<br>";
      output.innerHTML += JSON.stringify(iter.next()) + "<br>";
      output.innerHTML += JSON.stringify(iter.next()) + "<br>";
   </script>
</body>
</html>
{"value":"A","done":false}
{"value":"C","done":false}
{"value":"E","done":false}
{"done":true}
{"done":true}

上面的代码使用函数定义迭代器。因此,你不能将 for…of 循环与迭代器一起使用。让我们学习在下面的示例中使用对象定义迭代器。

The above code uses the function to define the iterator. So, you can’t use the for…of loop with the iterator. Let’s learn to define the iterator using the object in the example below.

Example

在下面的示例中,我们将函数添加为“Symbol.iterator”键的值。该函数返回 next() 方法。next() 方法返回奇数。如果奇数值为 9,它通过返回 {done: true} 对象完成迭代。

In the example below, we add a function as a value of the 'Symbol.iterator' key. The function returns the next() method. The next() method returns the odd numbers. If the value of the odd number is 9, it finishes the iteration by returning the {done: true} object.

在此,我们使用对象创建迭代器。因此,您可以使用 for…of 循环。循环将自动执行迭代器的 next() 方法,并返回由 next() 方法返回的对象的“value”属性。

Here, we created the iterator using the object. So, you can use the for…of loop. The loop will automatically execute the next() method of the iterator and returns a value of the 'value' property of the object returned by the next() method.

<html>
<head>
   <title> JavaScript - User defined iterators </title>
</head>
<body>
   <p id = "output"> </p>
    <script>
       const output = document.getElementById("output");
       // Empty object
       oddNum = {};
       // Add iterator
       oddNum[Symbol.iterator] = function () {
          let p = -1;
          done = false;
          return {
             next() {
                p += 2;
                if (p == 9) return { done: true }
                return { value: p, done: done };
             }
          };
       }
       for (const odd of oddNum) {
          output.innerHTML += odd + "<br>";
       }
   </script>
</body>
</html>
1
3
5
7

当需要自定义迭代的可迭代遍历时,您应当创建用户自定义迭代器。例如,遍历交替数组元素,从迭代器获取偶数或奇数,等等。

You should create user-defined iterators when they need customization in the traversal of iterable. For example, to traverse alternative array elements, to get even or odd numbers from an iterator, etc.