js迭代

本文介绍了JavaScript中的迭代概念,阐述了迭代在有序集合上的应用及其在数组等数据结构上的局限。接着,详细讨论了迭代器模式,它是解决迭代问题的一种方案,使得对象无需预先了解数据结构即可进行迭代。最后,讲解了可迭代协议,即通过Symbol.iterator属性实现的默认迭代器,揭示了内置类型的可迭代性,如字符串、数组等。

“迭代”的意思是按照顺序反复多次执行一段程序,通常会有明确的终止条件。ECMAScript 6 规范新增了两个高级特性:迭代器和生成器。使用这两个特性,能够更清晰、高效、方便地实现迭代。

1. 首先先要理解迭代:
在 JavaScript 中,计数循环就是一种最简单的迭代:

for (let i = 1; i <= 10; ++i) { console.log(i); }

循环是迭代机制的基础,这是因为它可以指定迭代的次数,以及每次迭代要执行什么操作。每次循环都会在下一次迭代开始之前完成,而每次迭代的顺序都是事先定义好的。
迭代会在一个有序集合上进行。(“有序”可以理解为集合中所有项都可以按照既定的顺序被遍历到,特别是开始和结束项有明确的定义。)
由于如下原因,通过这种循环来执行例程并不理想。

迭代之前需要事先知道如何使用数据结构。数组中的每一项都只能先通过引用取得数组对象,
然后再通过[]操作符取得特定索引位置上的项。这种情况并不适用于所有数据结构。
遍历顺序并不是数据结构固有的。通过递增索引来访问数据是特定于数组类型的方式,并不适 用于其他具有隐式顺序的数据结构。

很多语言都通过原生语言结构解决了这个问题,开发者无须事先知道如何迭代就能实现迭代操作。这个解决方案就是迭代器模式。

2.迭代器模式

迭代器模式(特别是在 ECMAScript这个语境下)描述了一个方案,即可以把有些结构称为“可迭代对象”(iterable),因为它们实现了正式的Iterable接口,而且可以通过迭代器 Iterator 消费。

3. 可迭代协议

实现 Iterable 接口(可迭代协议)要求同时具备两种能力:支持迭代的自我识别能力和创建实现Iterator 接口的对象的能力。在
ECMAScript 中,这意味着必须暴露一个属性作为“默认迭代器”,而且这个属性必须使用特殊的 Symbol.iterator
作为键。这个默认迭代器属性必须引用一个迭代器工厂函数,调用这个工厂函数必须返回一个新迭代器。

很多内置类型都实现了 Iterable 接口:

  • 字符串
  • 数组
  • 映射
  • 集合
  • arguments 对象
  • NodeList 等 DOM 集合类型
    检查是否存在默认迭代器属性可以暴露这个工厂函数:
let num = 1; 
let obj = {}; 
// 这两种类型没有实现迭代器工厂函数
console.log(num[Symbol.iterator]); // undefined 
console.log(obj[Symbol.iterator]); // undefined 
let str = 'abc'; 
let arr = ['a', 'b', 'c']; 
let map = new Map().set('a', 1).set('b', 2).set('c', 3); 
let set = new Set().add('a').add('b').add('c'); 
let els = document.querySelectorAll('div'); 
// 这些类型都实现了迭代器工厂函数
console.log(str[Symbol.iterator]); // f values() { [native code] } 
console.log(arr[Symbol.iterator]); // f values() { [native code] } 
console.log(map[Symbol.iterator]); // f values() { [native code] } 
console.log(set[Symbol.iterator]); // f values() { [native code] } 
console.log(els[Symbol.iterator]); // f values() { [native code] } 
// 调用这个工厂函数会生成一个迭代器
console.log(str[Symbol.iterator]()); // StringIterator {} 
console.log(arr[Symbol.iterator]()); // ArrayIterator {} 
console.log(map[Symbol.iterator]()); // MapIterator {} 
console.log(set[Symbol.iterator]()); // SetIterator {} 
console.log(els[Symbol.iterator]()); // ArrayIterator {}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值