ES6-ES11-第一部分-let、const、解构赋值、模板字符串、简化对象写法、箭头函数、函数参数默认值、rest 参数、扩展运算符、Symbol、迭代器、生成器、Promise、Set、Map(四)

简介: ES6-ES11-第一部分-let、const、解构赋值、模板字符串、简化对象写法、箭头函数、函数参数默认值、rest 参数、扩展运算符、Symbol、迭代器、生成器、Promise、Set、Map(四)

11. 迭代器

迭代器(Iterator)就是一种机制。它是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署 Iterator 接口,就可以完成遍历操作。

  1. ES6 创造了一种新的遍历命令 for…of 循环,Iterator 接口主要供 for…of 使用
  2. 原生具备 iterator 接口的数据(可用 for of 遍历)
    a) Array
    b) Arguments
    c) Set
    d) Map
    e) String
    f) TypedArray
    g) NodeList

Iterator 是对象上的一个属性:Symbol.Iterator

11.1 for of 遍历

const arr = ['apple', 'banana', 'orange']
    // for of 遍历
    console.log('for of 遍历 ---- 获取的是键值')
    for (const iterator of arr) {
      console.log(iterator)
    }
    // for in 遍历
    console.log('for in 遍历 ---- 获取的是键')
    for (const key in arr) {
      console.log(key)
    }
    console.dir(arr)

11.2 工作原理

a) 创建一个指针对象,指向当前数据结构的起始位置

let i = arr[Symbol.iterator]()
    console.log(i)

b) 第一次调用对象的 next 方法,指针自动指向数据结构的第一个成员

console.log(i)
    console.log(i.next())

c) 接下来不断调用 next 方法,指针一直往后移动,直到指向最后一个成员

d) 每调用 next 方法返回一个包含 value 和 done 属性的对象

console.log(i)
    console.log(i.next())
    console.log(i.next())
    console.log(i.next())
    console.log(i.next())
    console.log(i.next())

11.3 迭代器应用 – 自定义遍历数据

需要自定义遍历数据的时候,要想到迭代器。

注意:

返回的对象 done 一直为 false 会一直输出,for of 是以返回的对象 done 为 true 为停止条件。

// 声明一个对象
      const obj = {
        name: '对象',
        content: ['属性1', '属性2', '属性3', '属性4'],
        // 1. 先添加iterator接口
        [Symbol.iterator]() {
          // 5. 索引变量
          let index = 0
          // 6. 保存 obj 对象的 this
          const _this = this
          // Result of the Symbol.iterator method is not an object
          // 2. 返回的结果不是一个对象
          return {
            // undefined is not a function
            // 3. 使用 for of 遍历时,会创建一个指针对象,指针对象中有一个next方法
            next() {
              // 7. 判断是否遍历完成
              if (index < _this.content.length) {
                // Iterator result undefined is not an object
                // 4. 需要返回一个对象
                return {
                  value: _this.content[index++],
                  done: false,
                }
              } else {
                return {
                  value: undefined,
                  done: true
                }
              }
            },
          }
        },
      }
      // 使用 for of 遍历
      // 每次返回的结果是 content 的成员
      for (const iterator of obj) {
        console.log(iterator)
      }

12. 生成器

生成器是一个函数。生成器函数是 ES6 提供的一种异步编程解决方案,语法行为与传统函数完全不同。

// 生成器函数 function 与函数名中间需要有一个 *,靠左靠右都行
    function * gen() {
      console.log('hello')
    }
    // 生成器函数的执行
    // 直接调用不能运行,需要调用next()方法
    let i = gen()
    console.log(i)
    i.next()

生成器函数相当于一个迭代器对象

12.1 yield 语句

yield 可以看成函数的分割符,把函数分割成若干部分,由 next() 方法控制函数代码的执行。

function * gen() {
      console.log('第1个片段')
      yield 'yield 1'
      console.log('第2个片段')
      yield 'yield 2'
      console.log('第3个片段')
      yield 'yield 3'
      console.log('第4个片段')
    }
    let i = gen()
    i.next() // 执行第1个片段
    i.next() // 执行第2个片段
    i.next() // 执行第3个片段
    i.next() // 执行第4个片段

生成器函数可以使用 for of 遍历:

function * gen() {
      // console.log('第1个片段')
      yield 'yield 1'
      // console.log('第2个片段')
      yield 'yield 2'
      // console.log('第3个片段')
      yield 'yield 3'
      // console.log('第4个片段')
    }
    let i = gen()
    // console.log( i.next() ) // 执行第1个片段
    // console.log( i.next() ) // 执行第2个片段
    // console.log( i.next() ) // 执行第3个片段
    // console.log( i.next() ) // 执行第4个片段
for (const iterator of i) {
      console.log(iterator)
    }

12.2 生成器函数参数传递

function * gen( arg ) {
      console.log(arg)
      let res1 = yield 111
      console.log(res1)
      let res2 = yield 222
      console.log(res1)
      console.log(res2)
      let res3 = yield 333
      console.log(res3)
    }
    // 获取迭代器对象
    let i = gen( 'AAA' )
    console.log(i.next()) // 执行 next 可以获取yield后面的值
    // next参数可以传入实参,实参为yield语句的返回结果
    // 第二个next传入的实参为第一个yield返回的结果
    // 第x个next传入的实参从函数的第x个片段开始可以使用,为上一个yield语句的返回结果
    console.log(i.next('BBB')) 
    console.log(i.next('CCC')) 
    console.log(i.next('DDD')) 

12.3 生成器函数实例 - 1

生成器函数可以用于结果回调地狱。

回调地狱:

// 1s后输出111,2s后输出222,3s后输出333
      setTimeout(() => {
        console.log(111)
        setTimeout(() => {
          console.log(222)
          setTimeout(() => {
            console.log(333)
          }, 3000)
        }, 2000)
      }, 1000)

function f1() {
        setTimeout(() => {
          console.log(111)
          // 继续向下调用
          i.next()
        }, 1000)
      }
      function f2() {
        setTimeout(() => {
          console.log(222)
          i.next()
        }, 2000)
      }
      function f3() {
        setTimeout(() => {
          console.log(333)
          i.next()
        }, 3000)
      }
      // 声明生成器函数
      function * gen() {
        yield f1()
        yield f2()
        yield f3()
      }
      // 迭代器对象
      let i = gen()
      // 调用执行
      i.next()


相关文章
Vuex惊天漏洞!!!破解Vuex状态管理漏洞:让getters变量具有set赋值的能力,支持双向绑定
Vuex惊天漏洞!!!破解Vuex状态管理漏洞:让getters变量具有set赋值的能力,支持双向绑定
|
前端开发 JavaScript API
ES6-ES11-第一部分-let、const、解构赋值、模板字符串、简化对象写法、箭头函数、函数参数默认值、rest 参数、扩展运算符、Symbol、迭代器、生成器、Promise、Set、Map(五)
ES6-ES11-第一部分-let、const、解构赋值、模板字符串、简化对象写法、箭头函数、函数参数默认值、rest 参数、扩展运算符、Symbol、迭代器、生成器、Promise、Set、Map(五)
ArrayList集合常用方法,.set可以用来生成图片和赋值命名,array.remove(1),array.set(1,“xxxx”)可以修改指定位置,array.size可以获取元素的个数
ArrayList集合常用方法,.set可以用来生成图片和赋值命名,array.remove(1),array.set(1,“xxxx”)可以修改指定位置,array.size可以获取元素的个数
|
数据库
仅当指定列列表,且SET IDENTITY_INSERT为ON时,才能对自增列赋值
仅当指定列列表,且SET IDENTITY_INSERT为ON时,才能对自增列赋值
1961 0
|
C++ 容器
set容器-构造和赋值讲解
set容器-构造和赋值讲解
123 0
|
存储 C++ 容器
Map容器-构造和赋值讲解
Map容器-构造和赋值讲解
151 0
|
SQL 分布式计算 DataWorks
使用`SET`语句来定义变量并为其赋值
使用`SET`语句来定义变量并为其赋值
408 4
|
SQL 分布式计算 DataWorks
可以使用SET语句来定义变量并为其赋值
可以使用SET语句来定义变量并为其赋值
111 2
|
Java 机器人 开发者
使用Map批量赋值进行表单验证的实践
在Web应用程序中,表单验证是一个必不可少的环节,它可以确保用户提交的数据合法且完整。然而,传统的表单验证方法往往需要手动设置每一个验证规则,这无疑增加了开发者的负担。通过使用Map批量赋值功能,我们可以更高效地将表单数据批量赋值给验证对象,然后根据验证对象的属性进行验证。
|
人工智能 Java 机器人
实现Map批量赋值,我只需24秒搞定!
函数的功能是将一组键值对批量赋值给Map中的键。在Java中,通常使用Map的put方法逐个将键值对赋值给Map,但在某些场景下,可能需要一次性将多个键值对赋值给Map。