Iterator可迭代接口

数字舵手
• 阅读 1519

for..of..

for...of... 作为遍历所有数据结构的统一方式

for遍历普通数组

for in 遍历键值对

forEach 数组的遍历方法

const arr = [100,200,300,400]

for(const item of arr){
  console.log(item); //拿到的是每一个元素,而不是对应的下标
  if(item>300){
    break;
  }
}

//取代forEach方法,for..of..可以使用关键词break随时终止,forEach无法终止遍历
arr.forEach(function(item,index){

})

其他的遍历

//伪数组的遍历(arguments)
// dom操作时一些元素节点的列表 的遍历
//Set ,Map对象
const s = new Set(['foo',"bar"])
for(var i of s)
{
  console.log(i); //foo  bar
}

配合结构使用

const m = new Map()
m.set({a:1},"value")
m.set(true,100)
for(var mm of m){
  console.log(mm); //[ { a: 1 }, 'value' ]   [ true, 100 ]
}

//通过解构优化上面的for..of
for(var [key,value] of m){
  console.log(key,value); //{ a: 1 } value   ||   true 100
}

注意,遍历对象会报错

//遍历对象会报错
const ddd = {naz:"mcgee",baz:100}
for(var item of ddd){
  console.log(item); //TypeError: ddd is not iterable
}

Iterable 可迭代接口

for..of循环时一种数据统一遍历的方式

for...of... Object TypeError 为什么?

Es能够表示有结构的数据类型越来越多 array obj set map 组合形式

Iterable怎么理解,就是一种接口(规格标准),例如任意一种数据类型都有toString方法,因为他们实现了统一的规格标准(实现了统一的接口)

可迭代接口就是一种 可以被for..of..循环遍历访问的规格标准

换句话说,如果他实现了可迭代接口,他就能被for of循环遍历

什么是可迭代

  • 控制台测试 帮助->切换开发人员工具 查看输出结果
console.log([])
console.log(new Set())
console.log(new Map())

Iterator可迭代接口
我们发现可以被for -- of遍历的对象都有

  • proto -> Symbol(Symbol.iterator):f values()
  • iterator接口约定对象内部必须要挂载一个叫iterator的方法,这个方法返回一个带有next()方法的对象
  • 不断调用next,就可以实现对内部的遍历
const result = ["foo","bar","baz"]
const iterator = result[Symbol.iterator]()

console.log(iterator.next()) //{value: "foo", done: false}
console.log(iterator.next()) //{value: "bar", done: false}
console.log(iterator.next()) //{value: "baz", done: false}
console.log(iterator.next()) //{value: undefined, done: true}
const s = new Set([1,2,"as","foo"])
const it2 = s[Symbol.iterator]()
console.log(it2.next())
console.log(it2.next())
console.log(it2.next())
console.log(it2.next())
console.log(it2.next())

自定义一个iterable可迭代的接口

实现iterable可迭代接口需要满足

  1. 有[Symbol.iterator] 方法
  2. [Symbol.iterator] 方法返回一个对象,这个对象实现了迭代器接口 Iterator
  3. 返回的对象具有一个next 方法,
  4. next方法返回一个 IterationResult 迭代结果的对象
  5. 对象有两个参数 value是每次的值,done表示是否完成迭代
//对象实现一个iterable接口,对数组进行for..of

const _iterable = [1,23,4]

const ob = {
  [Symbol.iterator](){
      let index=0               //计数器,用于判断是否迭代完成
      return {                  
          next:function(){      
              return {
                  value:_iterable[index],
                  done:index++>=_iterable.length
              }
          }
      }
  }
}

for(var item of ob){
  console.log(item)
}

由于generator生成器也实现了iterator接口,因此上面方法可以进行改写

const ob = {
  * [Symbol.iterator](){    //简写:[Symbol.iterator]:function * (){}
      for(let item of _iterable)
      {
        yield item
      }
  }
}

for(var item of ob){
  console.log(item) //1,23,4
}

案例

//我想获取一个文件下的数据
const obj = {
  work:["吃饭","睡觉","打豆豆"],
  learn:["and","fuck","your"],
  gos:["mother"],

  //通过回调方式
  cb(callback){
    const result = [].concat(this.work,this.learn,this.gos)
    for(var item of result){
      callback(item)
    }
  },

  //实现iterator接口,外部通过for..of..方式
  [Symbol.iterator]:function (){
    const arr = [...this.work,...this.learn,this.gos]
    let index=0;
    return {
      next:function(){
        return {
          value:arr[index],
          done:index++>=arr.length
        }
      }
    }
  }
}

傻瓜方式...

//耦合度太高,如果obj更改,则我还要加个方法
for(const item of obj.work)
{
  console.log(item);
}
for(const item of obj.learn)
{
  console.log(item);
}

传统回调方式

//传统做法注册个回调
obj.cb(function(item){
  console.log(item);
})

for..of方式

//用可实现迭代接口
for(var item of obj){
  console.log(item);
}

Generator

生成器函数之前讲过

上面也使用生成器实现了iterable接口

案例:添加一个发号器

//发号器
function * creatId(){
  let id=1
  while(true){
    yield id++
  }
}
const g = creatId()
g.next()
g.next()
g.next()
点赞
收藏
评论区
推荐文章
Symbol卢 Symbol卢
4年前
js数组的遍历
js中数组的遍历1\.Map()方法Map映射的意思,可以看做是一个映射函数,所谓的映射。一个萝卜一个坑,一一对应的关系;语法:constarrArray();arr.map((item,index,arr)//函数体return;);//参数1:数组中的每一项(必选)//参数2:索引(可选)//参数3:当前遍历的数组本身(可选)//注
Karen110 Karen110
4年前
盘点JavaScript中数组遍历的全部方式(下篇)
前言JavaScript想必大家都不陌生了,上篇文章已经给大家介绍了7种数组遍历的方式,这篇文章继续介绍7种数组遍历的方式,这样一共14种遍历方式,基本上囊括了JavaScript中全部的数组遍历方式了。下面的内容,紧接上面文章的内容,一起来学习下吧八、Find通过寻找数组中的对象返回数组中符合目标函数条件的第一个元素。否则返回undefined,如下:九
Karen110 Karen110
4年前
盘点JavaScript中数组遍历的全部方式(上篇)
前言JavaScript想必大家都不陌生了,其中的字符串和数组大家经常都会用到,今天就让我们来说说这里面的数组对象的遍历吧,因为遍历经常使用的缘故,所以小编带着大家来解锁遍历的所有方法,以便大家能够更深入的了解数组遍历,并在实际项目中灵活运用。一、Entries这个是ES6中提供的用于遍历数组的方法,它会返回一个遍历器对象,Entries是对键值对的遍历。
Wesley13 Wesley13
3年前
java 基础知识
遍历遍历就是把这个数组的每个元素显示出来遍历的方法就是先定义这个数组的大小,然后用FOR循环来完成数组,例如doublescorenewdouble5;ScannerinputnewScanner(System.in);for(inti0;i<score.l
kenx kenx
4年前
Java 集合遍历与循环多种方式
前言Java中集合是非常常用非常重要的,应用是十分广泛的,作为集合这种数据结构,遍历循环方式也有很多种我们可以梳理总结不同的遍历方式,方便理解和运用List遍历方式1.List继承了Collection,是有序的列表。2.实现类有ArrayList、LinkedList、Vector、Stack等1.ArrayList是基于数组实现的,是
Wesley13 Wesley13
3年前
JAVA之forEach遍历集合
JAVA之forEach遍历集合在JDK8中,根据Lambda表达式的特性还增加了一个forEach(Consumeraction)方法来遍历集合,该方法所需要的参数是一个函数式接口importjava.util.ArrayList;importjava.util.List;
Stella981 Stella981
3年前
ES6——for
  forin和forof乍一听,以为是一样的,都是用来“遍历”的。但是,既然开发出了两个方法,那就一定有所区别iterable  首先,ES6中添加了一个iterable类型,翻译过来叫“可迭代”。  在ES6里,数组Arrray、集合Set以及Map(目前我还不了解……)都是“可迭代的”
Stella981 Stella981
3年前
JavaScript中遍历数组和对象的方法
js数组遍历和对象遍历针对js各种遍历作一个总结分析,从类型用处,分析数组和对象各种遍历使用场景,优缺点等JS数组遍历:1,普通for循环,经常用的数组遍历vararr1,2,0,3,9,10,20,
Wesley13 Wesley13
3年前
JAVA 数组遍历
一、遍历List1、增强for循环StringarrnewString{"xx","yy","zz"};for(Stringelt:arr){System.out.println(elt);}2、下标的方式String
Stella981 Stella981
3年前
JavaScript遍历循环
定义一个数组和对象constarr'a','b','c','d','e','f';constobj{a:1,b:2,c:3,d:4}for()经常用来遍历数组元素遍历值为数组元素索引f
小万哥 小万哥
1年前
NumPy 数组迭代与合并详解
NumPy数组迭代NumPy数组迭代是访问和处理数组元素的重要方法。它允许您逐个或成组地遍历数组元素。基本迭代我们可以使用Python的基本for循环来迭代NumPy数组。一维数组迭代:pythonimportnumpyasnparrnp.array(1