Object对象定义Iterator迭代器实现for...of遍历

前言

ECMAScript 6中新增了Iterator(迭代器)的概念,它提供了for…of语法对继承了Iterator的对象进行遍历,基本上很多数据集对象都继承了生成迭代器对象的函数,但Object对象却不继承Iterator生成器,即不支持for…of语法来遍历,因此如果我们需要对数据集的遍历使用for…of的方式统一标准,就得让Object对象也能实现Iterator遍历,实现Iterator的方法就是给Object对象定义一个Iterator生成函数,将函数绑定给Symbol(Symbol.iterator)属性,让函数返回一个可遍历对象,可遍历对象的设计参考原生的可遍历对象即可。


功能实现

这里提供两种方式,任意一种都可以实现,最后使用for…of循环测试一下效果,如果Object对象能够成功遍历,说明实现成功了。

方法一:将Object对象封装成数组

思路

由于数组继承了Iterator生成可遍历对象的函数,它支持通过for…of进行遍历,因此我们只需将Object对象拆开并重组成一个Array对象,再对Array对象进行遍历即可。

代码

const obj = {
	"name": "luckyboy",
	"sex": "male",
	"age": 20,
	"job": "coder"
}

//给对象定义一个Iterator函数,用于生成可遍历对象
obj[Symbol.iterator] = () => {
	//声明一个数组
	const arr = [];
	
	//遍历obj对象,将对象中的值插入到数组中
	for (let item in obj) {
		arr.push(obj[item]);
	}
	
	//将数组的Iterator函数生成的可遍历对象返回
	return arr[Symbol.iterator]();
}

//obj定义了上面的函数之后,for...of底层便会调用obj的Iterator生成可遍历对象
for (let item of obj) {
	console.log(item);
}

方法二:自定义可遍历对象

思路

给Object对象定义Iterator对象生成函数,并且在对象中定义一个next函数,它每次调用的时候都会索引到上次索引的下一个位置,这种写法是参考JavaScript原生可遍历对象的写法。

代码

const obj = {
	"name": "luckyboy",
	"sex": "male",
	"age": 20,
	"job": "coder"
}

//给对象定义一个Iterator函数,用于生成可遍历对象
obj[Symbol.iterator] = () => {
	//声明一个克隆对象,后续要对对象进行删除操作,但要保护源对象,所以只能对源对象进行克隆
	const cloneObj = {};
	
	//遍历obj中的内容,复制到克隆对象中
	for (let i in obj) {
		cloneObj[i] = obj[i];
	}
	
	//函数返回值,返回一个对象,该对象即是可遍历对象
	return {
		//返回的对象中定义一个next函数,每次调用会索引到下一个值
		next: function () {
			let value;
			
			/**
			 *	遍历克隆对象
			 *	注意:这里一定要用克隆对象,因为有删除操作,要保护源对象的完整性
			 */
			for (let item in cloneObj) {
				//将遍历的值存储,用于返回值
				value = cloneObj[item];
				//删除当前遍历的键值对
				delete cloneObj[item];
				break;
			}
			
			//值存在,证明遍历还在进行中
			if (value) {
				return {
					value,
					done: false
				}
			//值不存在,证明遍历已经结束
			} else {
				return {
					done: true
				}
			}
		}
	}
}

for (let item of obj) {
	console.log(item);
}

总结

尽量使用第一种方式吧,比较好理解一点,第二种则比较繁琐,需要对原生可遍历对象的结构比较了解。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值