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()


相关文章
|
8月前
|
前端开发 JavaScript API
ES6-ES11-第一部分-let、const、解构赋值、模板字符串、简化对象写法、箭头函数、函数参数默认值、rest 参数、扩展运算符、Symbol、迭代器、生成器、Promise、Set、Map(五)
ES6-ES11-第一部分-let、const、解构赋值、模板字符串、简化对象写法、箭头函数、函数参数默认值、rest 参数、扩展运算符、Symbol、迭代器、生成器、Promise、Set、Map(五)
|
8月前
|
前端开发 API 网络架构
ES6-ES11-第一部分-let、const、解构赋值、模板字符串、简化对象写法、箭头函数、函数参数默认值、rest 参数、扩展运算符、Symbol、迭代器、生成器、Promise、Set、Map(六)
ES6-ES11-第一部分-let、const、解构赋值、模板字符串、简化对象写法、箭头函数、函数参数默认值、rest 参数、扩展运算符、Symbol、迭代器、生成器、Promise、Set、Map(六)
|
1月前
ES6之Symbol
ES6之Symbol
|
3月前
|
JavaScript 前端开发
|
3月前
|
JavaScript 前端开发 开发者
|
1月前
|
JavaScript
js开发:请解释什么是ES6的Symbol,以及它的用途。
ES6的Symbol数据类型创建唯一值,常用于对象属性键(防冲突)和私有属性。示例展示了如何创建及使用Symbol:即使描述相同,两个Symbol也不等;作为对象属性如`obj[symbol1] = &#39;value1&#39;`;也可作枚举值,如`Color.RED = Symbol(&#39;red&#39;)`。
|
3月前
|
JavaScript 前端开发
ES6之原始数据类型Symbol
ES6 引入了一种新的原始数据类型Symbol,表示独一无二的值。它属于 JavaScript 语言的原生数据类型之一,其他数据类型是:undefined、null、布尔值(Boolean)、字符串(String)、数值(Number)、大整数(BigInt)、对象(Object)。Symbol的作用是创建一个不可变且唯一的标识符,可以用作对象属性的键。它可以用来解决属性名冲突的问题,避免命名冲突。
35 0
|
7月前
ES6: Symbol概念与用法举例
ES6: Symbol概念与用法举例
28 0
|
8月前
|
JavaScript
es6数据类型Symbol以及es6操作数组常用的方法
es6数据类型Symbol以及es6操作数组常用的方法
60 0

热门文章

最新文章