JavaScript - 用户定义迭代器



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

next() 方法

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

  • value - value 键包含元素作为值。

  • done - done 键包含布尔值。如果可迭代对象的所有迭代都已完成,则它包含 true。否则,它包含 false。

示例

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

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

<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}

用户定义迭代器

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

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

示例

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

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

<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 循环与迭代器一起使用。让我们在下面的示例中学习如何使用对象定义迭代器。

示例

在下面的示例中,我们将一个函数作为 'Symbol.iterator' 键的值添加。该函数返回 next() 方法。next() 方法返回奇数。如果奇数的值为 9,则它通过返回 {done: true} 对象来结束迭代。

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

<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

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

广告