JavaScript Iterator和for...of循环(一)

Iterator(遍历器)

概念
  • JavaScript原有的表示"集合"的数据结构,主要是数组和对象,ES6又添加了Map和Set.用户可以组合使用它们,定义自己的数据结构.这样就需要统一的接口机制处理所有不同的数据结构.Iterator就是这样一种机制,它是一种接口,为各种不同的数据结构提供统一的访问机制.任何数据结构只要部署Iterator接口,就可以完成遍历操作(即依次处理该数据结构的所有成员)
作用
  • 为各种数据结构提供统一的,简便的访问接口
  • 使数据结构的成员能够按照某种次序排列
  • ES6创造了一种新的遍历命令for…of循环,Iterator主要供其使用.也就是当使用for…of时,该循环会自动去寻找Iterator接口
Iterator的遍历过程:
  • 创建一个指针对象,指向当前数据结构的起始位置。也就是说,遍历器对象本质上,就是一个指针对象
  • 第一次调用指针对象的 next 方法,可以将指针指向数据结构的第一个成员
  • 第二次调用指针对象的 next 方法,指针就指向数据结构的第二个成员
  • 不断调用对象的next方法,直到它指向数据结构的结束位置
  • 每一次调用next方法都会返回数据结构的当前成员的信息.具体来说就是返回一个包含value和done两个属性的对象.value是当前成员的值,done属性是一个布尔值,表示遍历是否结束
var it=makeIterator(['a','b']);
it.next();	//{value:'a',done:false}
it.next();	//{value:'b',done:false}
it.next();	//{value:undefined,done:true}
function makeIterator(arr){
	var nextIndex=0;
	return {
		next : function(){
			return nextIndex < arr.length-1 ? 
			{value:arr[nextIndex++],done:false} : {value:undefined,done:true};
		}
	}
}
//这里的arr[nextIndex++]执行顺序是执行arr[nextIndex]; nextIndex++;
默认Iterator接口
  • ES6规定,默认的Iterator接口部署在数据结构的Symbol.iterator属性,或者说一个数据结构只要有Symbol.iterator属性就可以认为是可遍历的.Symbol.iterator属性本身是一个函数,就是当前数据结构默认的遍历器生成函数
  • ES6的有些数据结构原生具备Iterator接口,比如数组,即不用任何处理就能被for…of循环遍历.对象没有Iterator接口
  • 原生具备Iterator接口的数据结构:Array,Map,Set,String,TypedArray,NodeList对象,函数的arguments对象
  • 对于类似数组的对象(存在数值键名和length属性),部署Iterator接口,可以直接使其Symbol.iterator方法引用数组的Iterator接口.比如NodeList:NodeList.prototype[Symbol.iterator]=Array.prototype[Symbol.iterator].NodeList
  • 注意:普通对象部署数组的Symbol.iterator方法没有效果.因为普通对象的键值是字符串,不是数值键名
  • 有了遍历器接口,数据结构就可以用for…of循环遍历,也可以使用while循环遍历
调用iterator接口的场合
  • 解构赋值:对数组和Set结构进行解构赋值时,会默认调用Symbol.iterator方法
  • 扩展运算符(…)内部会调用Iterator接口.只要某个数据结构部署了Iterator接口,就可以对它使用扩展运算符,将其转为数组
  • yield*后面跟的是一个可遍历的结构,它会调用该结构的遍历器接口
let generator = function* () {
	yield 1;
	yield* [2,3,4];
	yield 5;
};
var iterator = generator();
iterator.next() // { value: 1, done: false }
iterator.next() // { value: 2, done: false }
iterator.next() // { value: 3, done: false }
iterator.next() // { value: 4, done: false }
iterator.next() // { value: 5, done: false }
iterator.next() // { value: undefined, done: true }
  • 其他场合:由于数组的遍历会调用遍历器接口,所以任何接受数组作为参数的场合,其实都调用了遍历器接口
遍历器对象的return(),throw()
  • 遍历器除了具有next方法,还可以具有return方法和throw方法.后两者是可选的
  • return()方法的使用场合是,如果for…of循环提前退出(通常是因为出错,或者有break和continue语句),就会调用return方法.如果一个对象在完成遍历前,需要清理或释放资源,就可以部署return方法
  • throw方法主要是配合generator函数使用,一般的遍历器对象用不到
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值