1. 迭代器: 如果一个对象具有next方法, 并且该next方法返回的对象带有value和done属性, 分别用来表示值和是否是迭代尽头, 那么这个对象就是迭代器.
2. 迭代和遍历的区别: 本人理解的迭代, 是一种表示数据的特殊形式, 并且这种形式不需要额外的存储空间.
比如: 一个斐波那契数列的迭代,可以很容易的用下面的方式表示:
1 function creatIterator() { 2 let prev1 = 1, 3 prev2 = 1, 4 n = 0; 5 6 return { 7 next: function () { 8 if (n < 2) { 9 value = 1; 10 } else { 11 value = prev1 + prev2; 12 } 13 14 prev2 = prev1; 15 prev1 = value; 16 n++; 17 return { 18 value, 19 done: false 20 } 21 } 22 } 23 24 }
通过var it = creatIterator(), it.next()就可以无限的获得下一个value. 而不需要用var arr = [1,1,2,3....]这种需要空间来存储;
3. 具有[Symbol.iterator]属性的对象是一个可迭代对象.
通过选择器选出的元素类数组, 普通数组,
如果没有这个属性, 需要添加这个属性, 就可以迭代了
var obj = { a: 1, b: 2, c: 3, [Symbol.iterator]: function(){ let keys = Object.keys(this), values = Object.values(this), n = 0, done ; return { next:function(){ return{ value: {[keys[n]]: values[n] }, done: n ++ < keys.length ? false : true } } } } };
所有带有[Symbol.iterator]属性的对象都可以用for of来遍历
4. Generator语法糖. *: 凡是加* 的函数都返回一个iteratorable的对象, 有next方法; 目的就是简化迭代过程.
是一个iterator的一个语法糖. 而yield 后面的表达式是next的停止点
用* 模拟async await;
1 function* task() { 2 const d = yield 1; 3 console.log(d); 4 const resp = yield fetch("http://127.0.0.1:3000/") 5 console.log(resp); 6 const a = yield resp.json(); 7 console.log(a); 8 } 9 run(task) 10 11 12 function run(task) { 13 14 const it = task(); 15 16 const next = it.next() 17 18 return handleResult(next); 19 function handleResult(next) { 20 const value = next.value; 21 if (next.done) return; 22 if (value instanceof Promise) { 23 value.then(res => { 24 handleResult(it.next(res)); 25 }) 26 } else { 27 handleResult(it.next()); 28 } 29 } 30 }