You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
letary=['a','b','c'];//数组letstr='str';//字符串letset=newSet();//Setset.add('s');set.add('s');set.add('e');set.add('t');letmap=newMap();//Mapleto={};map.set('m','m');map.set(o,'object');letobj={//对象name: 'syj',age: 24}functionforOf(list){for(varvalueoflist){console.log(value);}}forOf(ary);//a b cforOf(str);// s t rforOf(set);// s e tforOf(map);//[ 'm', 'm' ], [ {}, 'object' ]forOf(obj);//TypeError: list[Symbol.iterator] is not a function
constfibonacci={a: 'a',b: 'b',}console.log(...fibonacci);//TypeError://(var)[Symbol.iterator] is not a functionfibonacci[Symbol.iterator]=function(){let[pre,next]=[0,1];return{next(){[pre,next]=[next,pre+next];return{value: next,done: next>1000}}}}console.log(...fibonacci);//
Iterator
背景
ES5中的loop
for循环
这是标准for循环的写法,字符串也支持,定义一个变量i作为索引,以跟踪访问的位置,len是数组的长度,条件就是i不能超过len。
这种写法看起来算是比较简单明了的,只不过for里面要写一大坨,而且当出现嵌套的时候,要定义多个变量去维护不同集合的索引,增加复杂度,容易出错。
forEach
for-in
什么是迭代器
ES5模拟一个迭代器
createIterator可以看做一个返回迭代器对象的工厂函数,通过while循环调用返回的iterator.next()会得到result,直到done变为true。用ES5写还是比较麻烦的,而且我们这样写并不支持for...of。很快就会看到ES6真正的写法啦。
迭代器协议(Iteration protocols)
可迭代类型
尝试使用for...of
通过结果可以看出,确实集合类型和字符串都可以用默认的for...of来迭代。但是对象却不可以,内部抛出一个错误,找不到迭代器的接口,证实了上面的言论。
也许你不了解Set,Map,Set通常是类似于数组的,无重复项的集合,Map是类似于对象的,但是他的key可以是任何类型,增强版的“键值对”的数据结构。详情了解可以移步Set-Map。
可以访问默认的iterator
使对象可迭代
通过defineProperty向obj对象中添加[Symbol.iterator],我们在对应的value做的就是通过Object.keys取出它的key,然后调用一次next就往后找一位,可以通过next()尝试一下。因为obj有了[Symbol.iterator],for...of可以找到,并且调用。
通过直接声明给对象定义一个iterator。这里是iterator经典的用法。当这个数据集合特别大,甚至无限的时候,我们要把它定义好,取出来都是很庞大的操作,这时候iterator的优势就很明显了。只有调用一次next,才返回下一个值,不调用就没有。假如说我们给done没加限制条件,这个迭代器就永远没有done=true,就会永远可以next。为了防止for...of ,调用next的时候,有可能让我的电脑卡死,限制在1000以内。
还有一些值得关注的点
拓展运算符与iterator关系密切
第一次log我们尝试把fibonacci使用... 展开,但是会报错。把这行console注释掉以后,给这个对象添加一个Symbol.iterator属性,再次使用... ,就会得到之前的斐波那契数列了。 由于ES6的数组等集合默认有Symbol.iterator属性,所以我们都是可以直接使用扩展运算符。
类数组
总结
ES6提出迭代器的概念,契合了JS语言发展的趋势,统一处理数据结构。迭代器是ES6中很重要的部分,我们仅仅使用是很方便的,但是自定义一些iterator,或者更复杂的方式运行迭代器,还需要我们继续学习。
而定义一个对象的迭代器,又与Symbol对象有关,它采用了Symbol里面的一个默认属性iterator,用来访问对象的迭代器。最后可迭代的数据类型,我们都可以用for...of方法循环遍历,而且集合和字符串内置迭代器,我们可以轻松方便的访问。拓展运算符也是基于iterator的拓展,通过...我们可以把其他数据类型转化为数组,因为...通过执行迭代器,并读取返回的value。
下一篇我们还有未完成的高级迭代器-生成器。
The text was updated successfully, but these errors were encountered: