循环、遍历、迭代

215 阅读3分钟

循环:语言层面上的语法——> 重复执行一段程序的方案

遍历:业务层面上的做法——>观察或者获取集合中的元素的一种做法

迭代:实现层面上的概念——>实现遍历的底层方案其实就是迭代

/*循环*/
    var arr = [1,2,3];
    for (var i = 0;i<arr.length;i++){
        console.log(arr[i],i,arr)//重复执行这段程序
    }
/*数组方法*/
    arr.forEach(function(item,index,array){
        console.log(item,index,array)//针对数组比较直观的方法,并不是语法表述上的
    })
    
以上输出结果一样

数组的七个方法: forEach,map,filter,reduce,reduceRight,some,every

ECMAScript3:没有针对可迭代对象的具体的遍历方法

ECMAScript5:for in 对象的遍历方法

for...in :

  • 以任意顺序遍历一个对象的除Symbol以外的可枚举属性

  • 找的是对象的属性键名

  • 它是为遍历对象属性而构建的,不建议与数组一起使用,数组可以用forEach(),for...of

  • 常用于调试,方便检查对象属性

//for...in遍历普通对象
    var obj = {
        a:1,
        b:2,
        c:3
    }

    for (var key in obj){
        console.log(key,obj[key])
    }
//a 1
//b 2
//c 3

//for...in遍历数组
    var arr = [1,2,3]
    for (var key in arr){
    console.log(key,arr[key])
    }
//0 1
//1 2
//2 3

可以把数组看成一个“特殊”对象
//类数组
    var arr ={
        0:1,
        1:2,
        2:3,
        length:3,
        slice:Array.prototype.slice,
        splice:Array.prototype.splice,
        push:Array.prototype.push
    }
    for (var key in arr){
    console.log(key,arr[key])
    }
//0 1
//1 2
//2 3
//length 3
//slice ƒ slice() 
//splice ƒ splice() 
//push ƒ push() 

//for...in遍历Map、Set

    var m = new Map([ [{a:1},1] , [{b:2},2] , [{c:3},3] ])
    for (let k in m ){
        console.log(k)
    }//无法打印出来
    
    var s = new Set(['a','b','c'])
    for (let k in s ){
        console.log(k)
    }//无法打印出来

for...of:

  • for...of语句在可迭代对象(包括Array,Map,Set,String,TypedArray,arguments对象等)上创建一个迭代循环,调用自定义迭代钩子,并为每个不同属性的值执行语句
  • 找的是可迭代对象的value值
  • 不可用在Object上,Object属性是无序的,它没有迭代器

    var m = new Map([ [{a:1},1] , [{b:2},2] , [{c:3},3] ])
    for (let v of m ){
        console.log(v)
    }

//[{…}, 1]
    //0: {a: 1}
    //1: 1
    //length: 2
    //[[Prototype]]: Array(0)
//[{…}, 2]
    //0: {b: 2}
    //1: 2
    //length: 2
    //[[Prototype]]: Array(0)
//[{…}, 3]
    //0: {c: 3}
    //1: 3
    //length: 2
    //[[Prototype]]: Array(0)

for..in和for...of区别

  • for...in是以任意顺序迭代对象的可枚举属性(它是无序的)
  • for...of遍历可迭代对象定义要迭代的数据(是有序的)

生成器、迭代器、Symbol.iterator

  • 生成器generator:它的作用就是用来生成迭代器的
  • 迭代其实就是每次去执行一次next()函数
  • Iterator 接口就是对象里面的一个属性,这个属性的名字叫做 Symbol.iterator, 它是一个函数。 调用它会生成一个迭代器对象,该对象身上有一个 next 方法,调用 next 方法会返回一个包含 value 和 done 属性的对象
function *generator (arr){
    for (let v of arr){
        yield v //产出一个值,暂停一下
    }
}
var arr = [13,23,33]

const iterator = generator(arr)
console.log(iterator.next())//{value: 13, done: false}
console.log(iterator.next())//{value: 23, done: false}
console.log(iterator.next())//{value: 33, done: false}
console.log(iterator.next())//{value: undefined, done: true}

实现一个生成器函数:

//数组
function generator(arr){
    var index = 0
    return{
        /* 
        value:
        done:
        */
       next(){
        return index < arr.length
               ?
               {
                   value:arr[index++],
                   done:false
               }
               :
               {
                   value:undefined,
                   done:true
               }
       }
    }
}
//类数组(对象)
const o = {
    0:1,
    1:2,
    2:3,
    length:3
}

Object.prototype[Symbol.iterator] = iterator
function iterator(){
    var index = 0
    var _this = this
    return{
        /* 
        value:
        done:
        */
       next(){
        return index < _this.length
               ?
               {
                   value:_this[index++],
                   done:false
               }
               :
               {
                   value:undefined,
                   done:true
               }
       }
    }
}

    for(let v of o){
        console.log(v)
    }// 1 2 3