普通对象for..of...遍历的实现

背景

ES6提供for...of...结构可直接遍历数组的每个元素,不需要循环计数器变量,但该结构不适用于普通对象,测试如下:

// 测试数组
var arr = [10,20,30]
for(var ele of arr){
  console.log(ele);
}
// 依次输出 10 20 30

// 测试普通对象
var obj = {a:10,b:20,c:30}
for(var val of obj){
  console.log(val)
}
// 报错:obj is not iterable(obj不可迭代)

原因分析

ES6中部份数据结构(如数组)能用for...of...遍历,是因为它们本身提供了Iterator接口,所谓Iterator接口需要部署在对象的Symbol.Iterator属性上,属性值需为实现了如下功能的函数(摘自阮一峰老师 《ECMAScript 6 入门》):

function makeIterator(array) {
var nextIndex = 0;
return {
next: function() {
return nextIndex < array.length ?
{value: array[nextIndex++]} :
{done: true};
}
};
}

解决方案

为普通对象设置如下Symbol.Iterator属性,且设置在Object.prototype上

Object.prototype[Symbol.iterator]=function(){
      var that=this
      var keys=Object.keys(that);
      var index=0;
      return {
        next:function(){
      	return index<keys.length?{value:that[keys[index++]]}:{done:true}										 		             
             }
        }
}
// 再次测试
var obj = {a:10,b:20,c:30}
for(var val of obj){
  console.log(val)
}
// 依次输出 10 20 30 成功实现用用for...of...结构遍历普通对象
posted @ 2021-12-13 00:01  helloworld777  阅读(109)  评论(0编辑  收藏  举报