龙空技术网

理解JavaScript迭代器(一)

程序猿Dou哥 117

前言:

眼前兄弟们对“javascript高级程序设计第二版”都比较重视,看官们都想要了解一些“javascript高级程序设计第二版”的相关文章。那么小编也在网上汇集了一些有关“javascript高级程序设计第二版””的相关文章,希望小伙伴们能喜欢,大家快快来学习一下吧!

在 Js 中时刻都会用到迭代,迭代顾名思义就是按照顺序不断地执行一段程序,直到条件不满足或无可以迭代的数据为止。最简单的迭代就是普通的循环,举例:

//计数迭代for (let i = 0; i < 5; i++) {  console.log(i);}// 0 1 2 3 4 //数组迭代const arr = [1, 3, 5, 7, 9];for (let x = 0; x < arr.length; x++) {	console.log(arr[x]);}// 1 3 5 7 9

这种简单的迭代会有一些使用上的不便:计数迭代需要事先确定迭代次数,很多时候可能没法确定。迭代之前需要确定如何使用数据结构。数组迭代取值使用 [] 操作符取得索引位上的值,并不是所有数据结构都适用。并不是所有对象都像数组对象一样拥有固定的索引顺序,所以通过递增索引的方式来迭代的方式并不适用其他具有隐式顺序的数据结构ECMAScript6 增加了迭代器模式,把有些结构称为“可迭代对象”,因为它们实现了 Iterable 接口,而且可以通过迭代器 Iterator 消费。当需要迭代某个可迭代对象时,创建的迭代器是一个一次性对象,关联到指定的可迭代对象上,迭代器对象会暴露迭代其关联对象的API。这样迭代器无需知道数据的具体结构,只需要知道如果取得连续的值即可。

要实现 Iterable接口(可迭代协议),ECMAScript 要求必须提供一个属性作为默认迭代器,这个属性必须使用 Symbol.iterator 作为键,默认迭代器属性必须引用一个迭代器工厂函数,即调用这个工厂函数返回一个新的迭代器对象。Js 很多内置类型都实现了可迭代协议:StringArrayMapSetarguments对象NodeList等DOM集合类型

//检查是否存在默认迭代器属性let num = 1,obj = {}; //Number 和 默认对象不存在迭代器属性console.log(num[Symbol.iterator]);//undefinedconsole.log(obj[Symbol.iterator]);//undefinedlet str = 'abc';let arr = [1, 2, 3];let map = new Map().set('x', 1).set('y', 2).set('z', 3);let set = new Set().add('l').add('m').add('n');let eles = document.querySelectorAll('div');let all = [str, arr, map, set, eles];for (let i = 0; i < all.length; i++) {  // 这些类型都实现了迭代器工厂函数	console.log(all[i][Symbol.iterator]);  // ƒ [Symbol.iterator]() { [native code] }  // ƒ values() { [native code] }  // ƒ entries() { [native code] }  // ƒ values() { [native code] } *2}for (let i = 0; i < all.length; i++) {  // 调用工厂函数会生成一个迭代器 Iterator	console.log(all[i][Symbol.iterator]());  // StringIterator {}  // Array Iterator {}  // MapIterator {"x" => 1, "y" => 2, "z" => 3}  // SetIterator {"l", "m", "n"}  // Array Iterator {}}
实际使用中并不需要显式调用工厂函数来生成迭代器。实现可迭代协议的所有类型都会自动兼容接收可迭代对象的任何语言特性。接收可迭代对象的原生语言特性包括:for-of循环数组解构扩展操作符Array.from()方法创建集合创建映射Promise.all()接收由契约组成的可迭代对象Promise.race()接收由契约组成的可迭代对象yield*操作符,在生成器中使用

这些原生语言结构会自动在后台调用这个可迭代对象的工厂函数返回生成的迭代器

let arr = [1, 3, 5];for (let item of arr) {	console.log(item);}let [x,y,z] = arr;let arr2 = [...arr];let arr3 = Array.from(arr);let set = new Set(arr);let mapParams = arr.map((value, index)                         => [value, index]);let map = new Map(mapParams);//若对象原型链上的父类实现了Iterable接口,//则此对象也实现了这个接口

下一篇:

理解JavaScript迭代器(二)

参考资料:《JavaScript高级程序设计》

标签: #javascript高级程序设计第二版