JS表示集合的对象主要有Array、Set、Object、Map,在之前,遍历它们须要使用2种不一样的方法,而如今,JS提出了Iterator机制,能够给不一样的数据结构提供统一的遍历方法,就是for…of。换句话说,只有部署了Iterator的数据才能用for…of遍历。es6
Iterator的遍历过程是这样的:数组
(1)建立一个指针对象,指向当前数据结构的起始位置。也就是说,遍历器对象本质上,就是一个指针对象。数据结构
(2)第一次调用指针对象的next
方法,能够将指针指向数据结构的第一个成员。spa
(3)第二次调用指针对象的next
方法,指针就指向数据结构的第二个成员。prototype
(4)不断调用指针对象的next
方法,直到它指向数据结构的结束位置。指针
每一次调用next
方法,都会返回数据结构的当前成员的信息。具体来讲,就是返回一个包含value
和done
两个属性的对象。其中,value
属性是当前成员的值,done
属性是一个布尔值,表示遍历是否结束。code
ES6 规定,默认的 Iterator 接口部署在数据结构的Symbol.iterator
属性,或者说,一个数据结构只要具备Symbol.iterator
属性,就能够认为是“可遍历的”(iterable)。对象
默认部署了Iterator的数据有blog
-Array索引
-Map
-Set
-String
-arguments
-NodeList 对象
一个对象要被for…of遍历,必须部署Iterator,或者在其原型上部署Iterator,普通对象并无部署Iterator,若是用for…of遍历,会抛出“not iterable”错误
然而,一个相似于数组的普通对象直接调用数组的Symbol.iterator,也是能够用for…of遍历的
let iterable = { 0: 'a', 1: 'b', 2: 'c', length: 3, [Symbol.iterator]: Array.prototype[Symbol.iterator] }; for (let item of iterable) { console.log(item); // 'a', 'b', 'c' }
须要注意的是,“相似于数组”这个条件,不单单要以数字为索引,length属性也必不可少
两个条件中,任何一条不知足(就是普通对象),调用数组的Symbol.iterator是行不通的
那么普通对象到底要怎样才能被for…of遍历?
一是利用Object.keys获得对象的键名而后遍历这个数组
for (var key of Object.keys(someObject)) { console.log(key + ': ' + someObject[key]); }
Iterator的遍历过程看着像Generator,Generator能够很简单就实现Iterator接口,因此第二种方法就是利用Generator方法将对象包装一下
function* entries(obj) { for (let key of Object.keys(obj)) { yield [key, obj[key]]; } } for (let [key, value] of entries(obj)) { console.log(key, '->', value); }