迭代器 (Iterator) 和生成器 (Generator) 是 ES6 中非常重要的两个新特性,它们的出现极大地简化了 JavaScript 编程中对于集合型数据的操作。本文将详细介绍迭代器和生成器的概念、语法以及使用技巧,旨在帮助前端开发者更好地掌握这些新特性的使用。
迭代器 (Iterator)
在 JavaScript 中,如果想要遍历一个集合,通常需要使用 for 循环或者 forEach 方法。但是在 ES6 中,我们可以通过迭代器的方式来遍历一个集合,迭代器是一种统一的遍历集合数据的方式。迭代器通过一个 next 方法来返回集合中的每一个元素,直到集合中的所有元素被遍历完为止。
迭代器的语法
ES6 中标准的迭代器语法如下:
let arr = [1, 2, 3]; let iterator = arr[Symbol.iterator](); console.log(iterator.next()); // {value: 1, done: false} console.log(iterator.next()); // {value: 2, done: false} console.log(iterator.next()); // {value: 3, done: false} console.log(iterator.next()); // {value: undefined, done: true}
在上面的代码中,我们通过数组的 [Symbol.iterator]()
方法来获取其迭代器对象,然后通过迭代器对象的 next()
方法,依次输出数组中的每个元素。当遍历完数组中的所有元素后,next()
方法会返回 {value: undefined, done: true}
,表示遍历结束。
自定义迭代器
除了使用数组的迭代器对象,我们也可以自定义一个迭代器对象,实现集合的遍历操作。若要实现一个迭代器对象,必须实现一个 next()
方法,并且该方法返回一个包含 value
和 done
属性的对象。
-- -------------------- ---- ------- --- --- - - ----- --- -- --- ------------------- - --- ----- - -- --- ---- - ---------- --- ------ - ------------ ------ - ------ - -- ------ - ------- - ------ - ------ -------------- ----- ------ -- - ---- - ------ - ------ ---------- ----- ----- -- - -- -- -- -- --- -------- - ----------------------- ----------------------------- -- ------- -- ----- ------ ----------------------------- -- ------- -- ----- ------ ----------------------------- -- ------- -- ----- ------ ----------------------------- -- ------- ---------- ----- -----
上面的代码中,我们自定义了一个对象 obj,并实现了其迭代器对象的 next()
方法,通过 obj 的 [Symbol.iterator]()
方法获取其迭代器对象,再通过迭代器对象的 next()
方法,依次输出 obj 中的每个值。
可迭代对象
除了使用自定义迭代器对象,我们也可以让对象变为可迭代对象,从而可以直接使用 for 循环或者 forEach 方法进行遍历。
-- -------------------- ---- ------- --- --- - - ----- --- -- --- ------------------- - --- ----- - -- --- ---- - ---------- --- ------ - ------------ ------ - ------ - -- ------ - ------- - ------ - ------ -------------- ----- ------ -- - ---- - ------ - ------ ---------- ----- ----- -- - -- -- -- ------------------ --------- -- - --- ----- - -- --- ---- - ---------- --- ------ - ------------ ----- ------ - ------- - ----- -------------- - -- -- --- ---- - -- ---- - --------------- - --------------------- -- - --------------------- ---
上面的代码中,我们通过 [Symbol.iterator]: function* () {...}
的语法将 obj 转化为可迭代对象,并支持使用 for 循环和 forEach 方法进行遍历。
生成器 (Generator)
生成器 (Generator) 是 ES6 中的另一个重要新特性,它可以通过 yield
语句实现暂停函数的执行,从而实现函数执行过程的控制。
生成器的语法
生成器的语法和普通函数基本一致,不同之处在于函数名前面要加上一个星号*
,且函数体内可以包含 yield
语句。通过 yield
语句,函数可以在执行到该语句时暂停,并返回一个值,等待下一次调用时继续从该语句开始执行。
-- -------------------- ---- ------- --------- ------------- - ----- -- ----- -- ----- -- - --- -------- - -------------- ----------------------------- -- ------- -- ----- ------ ----------------------------- -- ------- -- ----- ------ ----------------------------- -- ------- -- ----- ------ ----------------------------- -- ------- ---------- ----- -----
上面的代码中,我们定义了一个生成器函数 myGenerator()
,函数体内含有三个 yield
语句,通过调用 iterator.next()
方法,依次输出每个 yield
语句的返回值。当生成器函数执行完所有的 yield
语句后,再次调用 next()
方法时便会返回 {value: undefined, done: true}
。
生成器实现异步编程
生成器可以通过 yield
语句暂停函数执行,然后由 next()
方法再次继续函数执行过程。我们可以基于这个特性,实现异步编程的效果。
-- -------------------- ---- ------- -------- --------- - ------ --- ----------------- ------- -- - --- --- - --- ----------------- --------------- ----- ---------------------- - -------- -- - -- --------------- --- -- - -- ----------- --- ---- - -------------------------- - ---- - ------------------- - - -- ----------- --- - --------- --------------- - --- - --- ------- - ----- ------------- --------------------- --- ------- - ----- ------------- --------------------- --- ------- - ----- ------------- --------------------- - ----- ------- - ------------------- - - --- -------- - ---------------- --- ------- - ---------------------- ------- -------------- -- - ----------------------------------------- -- - ---------------------- --- -- -------------- -- - ------------------- ---
上面的代码中,我们定义了一个生成器函数 ajaxGenerator()
,通过三个 yield ajax(url)
语句实现了三次异步请求,当所有异步请求完成后,在控制台输出每个请求的结果。我们通过调用 iterator.next().value
获取第一个异步任务的 Promise 对象,然后通过 promise.then()
语句的链式调用实现异步任务的串行执行。
总结
以上就是迭代器 (Iterator) 和生成器 (Generator) 的详细介绍和使用技巧,通过学习这些新特性可以更加轻松地操作集合型数据,同时也能够更好地理解 JavaScript 异步编程的实现原理。在实际的开发过程中,我们可以根据具体的业务场景灵活地运用这些技巧,提高代码的效率和可读性。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/6461ac7b968c7c53b0306560