当前位置: 代码迷 >> 综合 >> 学习ES6(二十)-- 迭代器
  详细解决方案

学习ES6(二十)-- 迭代器

热度:38   发布时间:2023-10-24 11:31:05.0

迭代器是一个对象,它使我们可以一次访问一组对象。

以下内置类型默认情况下是可迭代的-

  • String
  • Array
  • Map
  • Set

如果对象实现了键为[Symbol.iterator]并返回迭代器的函数,则该对象被视为迭代。for ... of循环可用于迭代集合。

let marks = [10,20,30]//check iterable using for..offor(let m of marks){console.log(m);}

下面的示例声明一个数组,标记并检索一个迭代器对象。的[Symbol.iterator]()可以被用于检索一个迭代器对象。迭代器的next()方法返回具有'value''done'属性的对象。'done'是布尔值,在读取集合中的所有项目后返回true。

<script>let marks = [10,20,30]let iter = marks[Symbol.iterator]();console.log(iter.next())console.log(iter.next())console.log(iter.next())console.log(iter.next())
</script>

输出:

{value: 10, done: false}
{value: 20, done: false}
{value: 30, done: false}
{value: undefined, done: true}

自定义迭代

JavaScript中的某些类型是可迭代的(例如,数组,映射等),而其他类型则不是。默认情况下不可迭代的JavaScript类型可以使用可迭代协议进行迭代。

下面的示例定义一个名为CustomerList的类,该类将多个客户对象存储为一个数组。每个客户对象都有firstName和lastName属性。

为了使此类可迭代,该类必须实现[Symbol.iterator]()函数。该函数返回一个迭代器对象。迭代器对象具有下一个返回对象{value:'customer',done:true / false}的函数。

<script>//user defined iterableclass CustomerList {constructor(customers){//adding customer objects to an arraythis.customers = [].concat(customers)}//implement iterator function[Symbol.iterator](){let count=0;let customers = this.customersreturn {next:function(){//retrieving a customer object from the arraylet customerVal = customers[count];count+=1;if(count<=customers.length){return {value:customerVal,done:false}}//return true if all customer objects are iteratedreturn {done:true}}}}}//create customer objectslet c1={firstName:'Sachin',lastName:'Tendulkar'}let c2={firstName:'Rahul',lastName:'Dravid'}//define a customer array and initialize it let customers=[c1,c2]//pass customers to the class' constructorlet customersObj = new CustomerList(customers);//iterating using for..offor(let c of customersObj){console.log(c)}//iterating using the next() methodlet iter = customersObj[Symbol.iterator]();console.log(iter.next())console.log(iter.next())console.log(iter.next())
</script>

输出:

{firstName: "Sachin", lastName: "Tendulkar"}
{firstName: "Rahul", lastName: "Dravid"}
{done: falsevalue: {firstName: "Sachin",lastName: "Tendulkar"}
}
{done: falsevalue: {firstName: "Rahul",lastName: "Dravid"}
}
{done: true}

Generator

在ES6之前,JavaScript中的函数遵循运行完成模型。ES6引入了称为Generator的功能,该功能可以在中途停止,然后从停止的地方继续。

生成器在函数名称前添加星号*字符,并包含一个或多个yield语句。yield关键字返回一个迭代器对象。

语法:

function * generator_name() {yield value1...yield valueN
}

该示例使用三个yield语句定义了生成器函数getMarks。与普通函数不同,生成器函数getMarks()在被调用时不会执行该函数,而是返回一个迭代器对象,该对象可帮助您在生成器函数内执行代码。第一次调用markIter.next()时,将运行操作,并且yield语句会暂停生成器的执行。随后对markIter.next()的调用将恢复生成器函数,直到下一个yield表达式为止。

<script>//define generator functionfunction * getMarks(){console.log("Step 1") yield 10console.log("Step 2")yield 20console.log("Step 3")yield 30console.log("End of function")}//return an iterator objectlet markIter = getMarks()//invoke statements until first yieldconsole.log(markIter.next())//resume execution after the last yield until second yield expressionconsole.log(markIter.next())//resume execution after last yield until third yield expressionconsole.log(markIter.next())console.log(markIter.next()) // iteration is completed;no value is returned
</script>

输出:

Step 1
{value: 10, done: false}
Step 2
{value: 20, done: false}
Step 3
{value: 30, done: false}
End of function
{value: undefined, done: true}
  相关解决方案