前端学习(六十三) JavaScript-iterator(javaScript)

Iterator

即迭代器,在ES6中加入,它的主要作用是为各种对象提供了统一的访问机制

例如,当我们使用for/of循环,内部其实调用了数组的Iterator

            let a=['a','b','c']
            for(let item of a){
                console.log(item);
            }

扩展:for/in和for/of

使用for in 也可以遍历数组,但是会存在以下问题:

1.index索引为字符串型数字,不能直接进行几何运算

2.遍历顺序有可能不是按照实际数组的内部顺序

3.使用for in会遍历数组所有的可枚举属性,包括原型。例如上栗的原型方法method和name属性

所以for in更适合遍历对象,不要使用for in遍历数组,用for of遍历数组。

记住,for in遍历的是数组的索引(即键名),而for of遍历的是数组元素值

for of遍历的只是数组内的元素,而不包括数组的原型属性method和索引name

那么什么是Iterator?

数组的Iterator是通过它的Symbol.iterator属性方法生成的

            let a=['a','b','c']
            let b=a[Symbol.iterator]()
            console.log(b.next());    //{value:'a',done:false}
            console.log(b.next());    //{value:'b',done:false}
            console.log(b.next());    //{value:'c',done:false}
            console.log(b.next());    //{value:underfined,done:true}

数组Symbol.iterator属性方法被调用时,返回当前数组的Iterator,可以通过Iterator的next()方法来访问数组中的各个成员(for/of内部通过对象的Iterator实现循环遍历)

可迭代协议

任意对象,只要实现了可迭代协议,它的内部成员就可以通过统一的语法被检索到

可迭代协议规定

一个对象是可迭代的,当它具有Symbol.iterator属性:该属性是一个无参数函数,被调用是返回一个Iterator(可以看作生成Iterator的工厂函数)

可迭代对象(也就是原生就实现了可迭代协议的对象)

有:array,arguments,set,Generator,Map,String,Typed Array

自定义一个可迭代对象

        class Foo{
                constructor(item){
                    this.item=item
                }
                [Symbol.iterator](){
                    let index=0;
                    const {items}=this
                    return {
                        next(){
                            const item =items[index++];
                            if(item){
                                return {
                                    value:item,done:false
                                }
                            }
                            else{
                                return {done:true}
                            }
                        }
                    }
                }
            }

扩展:扩展运算符(...)

https://blog.csdn.net/qq_30100043/article/details/53391308

扩展运算符内部也是基于Iterator

            let c=['a','b','c'];
            console.log([...c]);    //['a','b','c']

它和for of一样通过数组的Iterator访问数组中的每一个成员。通过它,可以将数组的每一项插入到新的数组中,从而实现数组的浅拷贝

            let d=['a','b','c'];
            let e=[...d];
            console.log(e);    //['a','b','c']
            console.log(d===e);    //false

另外扩展运算符还可以将任意可迭代对象转为数组

            let f="晴天";
            let f1=[...f]
            console.log(f1);    //['晴','天']

字符串处理

使用for循环等遍历字符串时,emoji(表情)等包含两个字符的码点会被拆分,而字符串的Iterator按照完成的Unicode码点进行迭代,可以利用这个特性处理包含emoji的字符串,进行字符串的截取,展示长度计算操作

            let str='天气晴(emoji)'
            for(let i=0;i<str.length;i++){    //不推荐,因为emoji式的表情不会被遍历到
                console.log(str[i]);
                
            }
            for(let i of str){    //推荐
                console.log(i);
                
            }

Generator

Generator既是一个Iterator也是一个可迭代对象,详情见Generator章节

猜你喜欢

转载自blog.csdn.net/zy21131437/article/details/81449054