"集合"数据的结构主要有
Array
、Object
、Set
andMap
,任何数据结构只要部署 Iterator 接口,就可完成遍历操做javascript
遍历过程:java
next
方法,对应指向数据结构成员,直至结束。每次调用
next方法,返回对象当前成员的信息
{value:text,done:true},其中
value表示成员值,
done` 表示遍历是否结束let arr = ['Owen','18']; let makeInterator = array =>{ let index = 0; return { next (){ return index < array.length ? {value:array[index++],done:false} : {value:undefined, done:true} } } } let inter = makeInterator(arr); inter.next() it.next() // { value: "Owen", done: false } it.next() // { value: 18, done: false } it.next() // { value: undefined, done: true }
对与遍历器对象来讲 done: false
and value:undefined
可省略数组
原生具有 Iterator 的数据结构:Array
、 String
、 Map
、 Set
、arguments
and NodeList
数据结构
都默认部署
[Symbol.iterator]
方法this
// const obj = { [Symbol.iterator] : function () { return { next: function () { return { value: 1, done: true }; } }; } }; obj[Symbol.iterator]().next() //{value: 1, done: true} let arr = ['a', 'b', 'c']; let iter = arr[Symbol.iterator](); iter.next() // { value: 'a', done: false } iter.next() // { value: 'b', done: false } iter.next() // { value: 'c', done: false } iter.next() // { value: undefined, done: true } iter.next() // { value: undefined, done: true }
对象(Object)之因此没有默认部署 Iterator 接口,是由于对象的哪一个属性先遍历,哪一个属性后遍历是不肯定的,须要开发者手动指定。prototype
//原型上部署Interator class RangeIterator { constructor(start, stop) { this.value = start; this.stop = stop; } [Symbol.iterator]() { return this; } next() { var value = this.value; if (value < this.stop) { this.value++; return {done: false, value: value}; } return {done: true, value: undefined}; } } function range(start, stop) { return new RangeIterator(start, stop); } for (var value of range(0, 3)) { console.log(value); // 0, 1, 2 } //对象上部署Interator function Obj(value) { this.value = value; this.next = null; } Obj.prototype[Symbol.iterator] = function() { var iterator = { next: next }; var current = this; function next() { if (current) { var value = current.value; current = current.next; return { done: false, value: value }; } else { return { done: true }; } } return iterator; } var one = new Obj(1); var two = new Obj(2); var three = new Obj(3); one.next = two; two.next = three; for (var i of one){ console.log(i); // 1, 2, 3 }
Array.prototype[Symbol.iterator]
//NodeList NodeList.prototype[Symbol.iterator] = Array.prototype[Symbol.iterator]; // 或者 NodeList.prototype[Symbol.iterator] = [][Symbol.iterator]; [...document.querySelectorAll('div')] //obj 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' }
// 解构赋值 let set = new Set().add('a').add('b').add('c'); let [x,y] = set; // x='a'; y='b' let [first, ...rest] = set; // first='a'; rest=['b','c']; //扩展运算符 var str = 'hello'; [...str] // ['h','e','l','l','o'] let arr = ['b', 'c']; ['a', ...arr, 'd'] // ['a', 'b', 'c', 'd'] //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 } // for...of //for...of循环可使用的范围包括数组、Set 和 Map 结构、某些相似数组的对象(好比arguments对象、DOM NodeList 对象)、 Generator 对象,以及字符串。 let arr = document.querySelectorAll("p"); for (let item of arr ) { console.log(item) } /* 其余操做*/ Array.from() Map(), Set(), WeakMap(), WeakSet() //生成对应数据结构 Promise.all() Promise.race()
return方法必须返回一个对象。
若是一个对象在完成遍历前,须要清理或释放资源,就能够部署return方法。
若是for...of循环提早退出(一般是由于出错,或者有break语句),就会调用return方法。指针
function readFile(file) { return { [Symbol.iterator]() { return { next() { return {done:false} }, return(){ file.close() return {done:true} } }; } }; } //触发 return() for (let line of readFile(fileName)) { console.log(line); break; } //触发 return() for (let line of readLinesSync(fileName)) { console.log(line); throw new Error(); }
let arr = [1,2]; //普通 `for`循环 for (var index = 0; index <arr.length; index++) { console.log(arr[index]); } /** * 书写比较麻烦 */ // Array.forEach arr.forEach(function(item){ console.log(item) }) /** * 没法跳出循环,没法使用 break or return */ // for...in for (let index in arr) { console.log(arr[index]); } /** * 1.数组键名为字符串形式的数字 * 2.会遍历出原型链上的键,和手动添加的键 * 3.有些状况是无顺序遍历 */ for (let item of arr) { console.log(item); } /** * 1.语法简洁 * 2.没有 for...in 的缺点 * 3.可使用 return、break and continue * */