学会javascript之迭代器

目录
  • 简介
  • js 中的迭代器是什么样子的
  • 迭代协议
    • 可迭代协议
    • 迭代器协议
    • 迭代过程
    • 迭代总结
  • 自定义迭代
    • 传统写法
    • 生成器函数写法

简介

  迭代器是一种设计模式,可在容器对象 如 链表、数组上遍历,无需关心容器对象的内存分配的实现细节。简单的理解就是可以一个一个的依次拿到其中的数据,类似一个移动的指针,但是会告诉我们什么时候结束。这样我们可以拿到数据之后可以做一些我们需要做的事情。

js 中的迭代器是什么样子的

  在javascript 中迭代器是一个特殊对象,这个迭代器对象有一个next()方法,每次调用都返回一个对象(结果对象)。结果对象有两个属性:一个是value,表示下一个将要返回的值;另一个是done,它是一个布尔类型的值,如果已经迭代到序列中的最后一个值,则它为 true。迭代器还会保存一个内部指针,用来指向当前集合中值的位置,每调用一次next()方法,都会返回下一个可用的值,类似下面这个对象的结构。

{
  next: function () {
        return {
            value:'',
            done: true / false
        }
    }
} 

迭代协议

  随着javascript 语言的能力进一步提升,新增了一些新的数据类型 如 Map、Set、WeakMap 等,为了这些不同的数据结构,可以统一的迭代,es6 增加了迭代协议这个东西。

迭代协议并不是新的内置实现或语法,而是协议。这些协议可以被任何遵循某些约定的对象来实现。

迭代协议具体分为两个协议:可迭代协议和迭代器协议。

简单的理解就是在js 中任何对象只要满足迭代协议就可以遍历

可迭代协议

要成为可迭代对象, 一个对象必须实现 @@iterator 方法。这意味着对象(或者它原型链上的某个对象)必须有一个键为 @@iterator 的属性,可通过常量 Symbol.iterator 访问该属性:

简单的理解,你想让一个东西可以遍历,那么这个东西要有一个 @@iterator ,这个属性可以通过Symbol.iterator 访问


属性



[Symbol.iterator]


一个无参数的函数,其返回值为一个符合迭代器协议的对象。

迭代器协议

迭代器协议定义了产生一系列值(无论是有限个还是无限个)的标准方式。当值为有限个时,所有的值都被迭代完毕后,则会返回一个默认返回值。

只有实现了一个拥有以下语义(semantic)的 next() 方法,一个对象才符合迭代器协议:


属性



next


一个无参数函数,返回一个应当拥有以下两个属性的对象:

done(boolean)

next() 方法必须返回一个对象,该对象应当有两个属性: done 和 value,如果返回了一个非对象值(比如 false 或 undefined),则会抛出一个 异常("iterator.next() returned a non-object value")。

迭代过程

当一个对象需要被迭代的时候(比如被写入一个 for...of 循环时),首先,会不带参数调用它的 @@iterator 方法( 此时返回的是结构是这样的 { next: function () {}}),然后使用此方法返回的迭代器获得要迭代的值(其实就是不断的调用这个next()方法)

迭代总结

迭代协议可以总结为,一个东西要遍历,必须满足可迭代协议跟迭代器协议

  • 可迭代协议:这个对象必须有@@iterator,可以通过Symbol.iterator 访问
  • 迭代器协议:是一个对象,这个对象的next() 函数返回一个对象,这个对象包括两个属性,一个是value,一个是done(boolean,是否是最后一个元素,done 为 true 时 value 可省略)

也就是说 迭代器对象本质上,就是一个指针对象。通过指针对象的next(),用来移动指针。

自定义迭代

对象是没有实现迭代器,所以不能遍历对象,为了可以实现对象的遍历,我们需要在对象上实现上面说的迭代器,通常有两种写法,一种是传统的写法,这种需要自己去控制内部的状态,另外一种是利用生成器函数返回的Generator的迭代器来实现,代码如下:

传统写法

let obj = {
  name: 'joel',
  adress: 'gz',
  [Symbol.iterator]: () => {
     // 这里不要用this, 因为是return fn, this 会丢失
    let index = -1, atrrList = Object.keys(obj);
    const objIterator = {
      next: () => {
        let result = ''
        index++
        if (index < atrrList.length) {
          result = {
            value: atrrList[index],
            done: false
          }
        } else {
          result = {
            done: true
          }
        }
        return result
      }
    }
    return objIterator
  }
}

for (const item of obj) {
    console.log('atrrs:' + item + ',value:' + obj[item])
}

生成器函数写法

// 为不可迭代的对象添加迭代器
let obj = {
  a: 1,
  b: 2
}
obj[Symbol.iterator] = function* () {
  let keys = Object.keys(obj);
  //取到key值的长度
  let len = keys.length;
  //定义循环变量
  let n = 0;
  //条件判断
  while (n <= len - 1) {
      yield { k: keys[n], v: obj[keys[n]] };
      n++
  }
}
//返回的是个对象的key和value
for (let { k, v } of obj) {
  console.log(k, v);
}

其他相关如内置可迭代对象、用于可迭代对象的语法、接受可迭代对象的内置api 等 请点击 这里

到此这篇关于学会javascript之迭代器的文章就介绍到这了,更多相关javascript 迭代器内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 学习JavaScript设计模式之迭代器模式

    迭代器模式是指提供一种方法顺序访问一个聚合对象中的各个元素,而又不需要暴露该对象的内部表示. JavaScript中的Array.prototype.forEach 一.jQuery中的迭代器 $.each([1, 2, 3], function(i, n) { console.log("当前下标为:"+ i + " 当前元素为:"+ n ); }); 二.实现自己的迭代器 var each = function(ary, callback) { for(var i

  • javascript设计模式之迭代器模式

    迭代器模式分为内部迭代器和外部迭代器,内部迭代器就是在函数内部定义好迭代的规则,它完全接手整个迭代的过程,外部只需一次初始调用. 内部迭代器 以下自行实现的类似jquery中$.each()的each()函数就是内部迭代器 //实现一个jq的$.each()迭代器 var arr = [1, 2, 3, 4, 5, 6, 7, 8] var each = function(arr, callback){ for(var i=0; i<arr.length; i++){ callback.call

  • 总结javascript中的六种迭代器

    1.forEach迭代器 forEach方法接收一个函数作为参数,对数组中每个元素使用这个函数,只调用这个函数,数组本身没有任何变化 //forEach迭代器 function square(num){ document.write(num + ' ' + num*num + '<br>'); } var nums = [1,2,3,4,5,6,7,8]; nums.forEach(square); 在浏览器中输出的结果是: 2.every迭代器 every方法接受一个返回值为布尔类型的函数,

  • javascript设计模式 – 迭代器模式原理与用法实例分析

    本文实例讲述了javascript设计模式 – 迭代器模式原理与用法.分享给大家供大家参考,具体如下: 介绍:迭代器模式是一种使用频率非常高的设计模式,通过引入迭代器,可以将数据的遍历功能从聚合对象中分离出来.迭代器模式用于顺序访问集合对象的元素,不需要知道集合对象的底层表示. 定义:提供一种方法来访问聚合对象,而不用暴露这个对象的内部表示,其别名为游标(Cursor).迭代器模式是一种对象行为型模式. 场景:我们做一个百家姓的迭代器 示例: function NameRepository(){

  • javascript天然的迭代器

    它源于群里的某一题目: 有一个数n=5,不用for循环,怎么返回[1,2,3,4,5]这样一个数组 群的"糖果男孩"给的答案: 复制代码 代码如下: function getArr(n) {      var a = [],          b = [],          m = 0;      a.length = n + 1;      a.toString().replace(/,/g, function () {          b.push(++m);      });

  • 学会javascript之迭代器

    目录 简介 js 中的迭代器是什么样子的 迭代协议 可迭代协议 迭代器协议 迭代过程 迭代总结 自定义迭代 传统写法 生成器函数写法 简介 迭代器是一种设计模式,可在容器对象 如 链表.数组上遍历,无需关心容器对象的内存分配的实现细节.简单的理解就是可以一个一个的依次拿到其中的数据,类似一个移动的指针,但是会告诉我们什么时候结束.这样我们可以拿到数据之后可以做一些我们需要做的事情. js 中的迭代器是什么样子的 在javascript 中迭代器是一个特殊对象,这个迭代器对象有一个next()方法

  • JavaScript数组迭代器实例分析

    本文实例讲述了JavaScript数组迭代器用法.分享给大家供大家参考.具体如下: 这里注意:如果数组中有0.false."".null.NaN迭代器将会停止 function createIterator(x) { var i = 0; return function(){ return x[i++]; }; } var iterator=createIterator(['a','b','c','d','e','f','g']); var current; while(current

  • 一分钟学会JavaScript中的try-catch

    导读: 在Java中我们使用try-catch进行异常处理,同样的JavaScript也提供了和异常处理类似的异常处理机制,本节我们将对JavaScript异常处理进行详细讲解. 1.1 如何进行错误处理 <script> var i = {}; //定义一个变量 i.func(); //调用一个不存在的方法 console.log("test"); //如果上一段代码出现错误,这段代码不会执行 </script> 查看控制台输出结果 从图1-1中能看出,当前程

  • JavaScript前端迭代器Iterator与生成器Generator讲解

    目录 Iterator 概念 默认 Iterator 接口 Iterator 的 return() 原生具备 Iterator 接口的数据结构 调用 Iterator 接口的场合 模拟实现 for of Generator 认识 Generator next 方法的参数 yield 表达式 Generator 与 Iterator 之间的关系 Generator.prototype.return() yield* 表达式 Generator 函数的 this Generator 实现一个状态机

  • 干货分享:让你分分钟学会javascript闭包

    闭包,是 javascript 中重要的一个概念,对于初学者来讲,闭包是一个特别抽象的概念,特别是ECMA规范给的定义,如果没有实战经验,你很难从定义去理解它.因此,本文不会对闭包的概念进行大篇幅描述,直接上干货,让你分分钟学会闭包! 1.闭包--爱的初体验 在接触一个新技术的时候,我首先会做的一件事就是:找它的demo code.对于码农们来说,代码有时候比自然语言更能理解一个事物. 其实,闭包无处不在,比如:jQuery.zepto的主要代码都包含在一个大的闭包中,所以下面我先写一个最简单最

  • Javascript的迭代器和迭代接口详解

    目录 1,什么是迭代器 2,自定义迭代接口 3,原生语言的迭代 总结 1,什么是迭代器 每一个可迭代对象都对应着一个可迭代接口[Symbol.iterator]: [Symbol.iterator]接口并不是迭代器,他是一个迭代器工厂函数,调用该迭代接口即可返回一个待执行状态的迭代器: 不同的原生全局对象都对应着不同的迭代器: const arr = new Array() const map = new Map() const set = new Set() console.log(arr[S

  • JavaScript中的迭代器和生成器详解

    处理集合里的每一项是一个非常普通的操作,JavaScript提供了许多方法来迭代一个集合,从简单的for和for each循环到 map(),filter() 和 array comprehensions(数组推导式).在JavaScript 1.7中,迭代器和生成器在JavaScript核心语法中带来了新的迭代机制,而且还提供了定制 for-in 和 for each 循环行为的机制. 迭代器 迭代器是一个每次访问集合序列中一个元素的对象,并跟踪该序列中迭代的当前位置.在JavaScript中

  • JavaScript中Iterator迭代器接口和循环

    目录 JavaScript的迭代器(Iterator)介绍 for...of循环与for...in循环 JavaScript的迭代器(Iterator)介绍 迭代器是数据结构遍历的一种机制(或者是什么我也不太懂的行业术语),为数据结构定义了统一的遍历规则. 迭代器(Iterator)主要是提供for...of使用,或者说,数据结构只有实现了迭代器(Iterator)接口才能使用for...of进行遍历数据,当一种数据结构没有实现迭代器(Iterator)接口时,去使用for...of操作,就会被

  • 什么是JavaScript

    什么是JavaScript JavaScript是一种基于对象和事件驱动的客户端脚本语言. JavaScript最初的设计是为了检验HTML表单输入的正确性. JavaScript起源于Netscape公司的LiveScript语言. JavaScript的历史 JavaScript最初起源于LiveScript语言,当互联网开始流行时,越来越多的网站开始使用HTML表单与用户交互,然而表单交互却成了制约网络发展的重大瓶颈(用户总是痛苦的等待数据传送到服务器端检测,并传回是否正确,仅仅的表单检测

随机推荐