前端进阶攻略之迭代器

前端进阶攻略之迭代器

在这里插入图片描述

一.什么是迭代器?

1.什么是迭代?

从一个数据集合中按照一定的顺序,不断的取出数据的过程

2.迭代和遍历的区别?

迭代强调的依次取出,不能确定可以取出的值有多少,也不能保证去把数据全部取完

遍历必须保证数据的长度,循环不断的全部取出,针对于数据量过大的情况下使用遍历,需要时间过长

3.迭代器

对迭代过程的封装,通常表现为对象的数据形式(也可以使用数组),不同语言中,表现出了的迭代形式不一样

4.迭代模式

一种编程设计模式,用于同一迭代的过程,并且规范迭代器的格式

二.JS原生迭代器

在写原生迭代器时,首先要明白迭代器的原理
迭代器需要满足的条件:
2.1.取出下一个数据的能力
2.2.判断是否有下一个数据

        function iterator(arr){
            return{
            i:0,
            next(){
            var result={
                value:arr[this.i],
                done:this.i>=arr.length
                } 
            this.i++;
            return result;
                 }
             }
        }
        var arr1=[1,2,3,4,5,6];
        let it=iterator(arr1);

只要知道迭代器需要满足的条件,写一个原生迭代器还是非常简单的
最终在控制台中调用.next()方法输出的结果为:
在这里插入图片描述
如果用while()循环可以让迭代器自己取数据,直到没有数据为止

        const arr = [1,2,3,4,5]
        const iterator ={  //用于迭代数组的对象,iterator为迭代器的名称
            i : 0,
            next(){
                var result = {
                    value : arr[this.i],
                    done : this.i >= arr.length
                }
                this.i ++;
                return result;
            }
        }
        console.log(iterator)
        // 让迭代器自己取数据,直到没有数据为止
        let data = iterator.next();
        while(!data.done){
            console.log(data.value)
            data = iterator.next();
        }
        console.log("迭代完成");

三.ES6中的迭代器

在es6中如果对象具有知名符号属性Symbol.iterator,则表示该对象可以迭代

        const arr = [464, 878, 88, 22, 45, 4, 8, 7]
            // // 在es6中如果对象具有知名符号属性Symbol.iterator,则表示该对象可以迭代
        console.log(arr)
        const iterator = arr[Symbol.iterator](); //es6之后,数组可以直接创建迭代对象
        console.log(iterator.next());  //{value: 464, done: false}
        console.log(iterator.next());  //{value: 878, done: false}
        console.log(iterator.next());  //{value: 88, done: false}
        console.log(iterator.next());
        console.log(iterator.next());
        console.log(iterator.next());
        console.log(iterator.next());
        console.log(iterator.next());

使用es6中的知名符号Symbol.iterator可以直接创建一个迭代对象,通过调用迭代对象的next()方法,可以直接迭代数组中的数据

3.1、使用迭代器生成斐波那契数列

下面我们就使用迭代器来自定义自己的一个斐波那契数列组,我们直到斐波那契数列有两个运行前提,第一个前提是初始化的前两个数字为0,1,第二个前提是将来的每一个值都是前两个值的和。这样我们的目标就是每次都迭代输出一个新的值。

 <!-- 1 1 2 3 5 8 13..... -->
    <!-- 创建一个分斐波那契数列的迭代器 -->
        function createFeibo(){
            let prev1 = 1;
            let prev2 = 1; //前两位
            let n = 1;//当前第几位
            return {
                next(){
                    let value;
                    if(n <=2 ){
                        value = 1
                    }else{
                        value = prev1 + prev2;
                    }
                    const result = {
                        value,
                        done: false
                    }
                    prev2 = prev1;
                    prev1 = result.value;
                    n++;
                    return result
                }
            }
        }
        const iter = createFeibo()

在 ES6 中常用的集合对象(数组、Set/Map集合)和字符串都是可迭代对象,这些对象都有默认的迭代器和Symbol.iterator属性。

通过生成器创建的迭代器也是可迭代对象,因为生成器默认会为Symbol.iterator属性赋值。

四. for of循环

for of 循环遍历、 就是专门针对可迭代对象的, 不是可迭代对象不能使用 forof循环。

        const arr1 = [1, 2, 3, 4, 5, 6, 7];
        for (let item of arr1) {
            console.log(item)
        }

for of与for in 区别:

区别①:for of无法循环遍历对象

var userMsg = {
    0: 'nick',
    1: 'freddy',
    2: 'mike',	
    3: 'james'
};
 
for(var key in userMsg){
    console.log(key, userMsg[key]);	
}
console.log('-----------分割线-----------');
for(var item of userMsg){	
    console.log(item);

在这里插入图片描述
区别②:遍历输出结果不同


var arr = ['nick','freddy','mike','james'];
for(var key in arr){
    console.log(key);	
}
console.log('-----------分割线-----------');
for(var item of arr){	
    console.log(item);
}

在这里插入图片描述
不难看出,for in循环遍历的是数组的键值(索引),而for of循环遍历的是数组的值。

区别③:for in 会遍历自定义属性,for of不会


var arr = ['nick','freddy','mike','james'];
arr.name = "数组";
 
for(var key in arr){
    console.log(key+': '+arr[key]);	
}
console.log('-----------分割线-----------');
for(var item of arr){	
    console.log(item);

在这里插入图片描述

给数组添加一个自定义属性name,并且赋值"数组"。然后进行遍历输出的,会发现新定义的属性也被for in输出来了,而for of并不会对name进行输出。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值