ES6之迭代器的知识点 面试必备

目录

 1,什么是迭代器?

1,通俗来讲迭代器就是帮助我们对某个数结构进行遍历的对象(迭代器是一个对象)面试问到直接这么答即

2,迭代器是一个具体的对象,但是整个对象要符合迭代器协议(迭代器协议定义了产生一系列值(无论是有限还是无限个)的标准方式,那么在js中这个标准就是一个特定的next方法)

3,next方法有几个要求

 2,迭代器 案列

 3,可迭代对象

 4,自定义类的迭代


1,什么是迭代器?

1,通俗来讲迭代器就是帮助我们对某个数结构进行遍历的对象(迭代器是一个对象)面试问到直接这么答即

2,迭代器是一个具体的对象,但是整个对象要符合迭代器协议迭代器协议定义了产生一系列值(无论是有限还是无限个)的标准方式,那么在js中这个标准就是一个特定的next方法

3,next方法有几个要求

  1. 一个无参或者有参的函数,返回一个应当拥有一下两个属性的对象
  2. done(boolean)
    1. 如果迭代器可以产生序列中的下一个值则为false
    2. 如果迭代器已将序列迭代完毕,则返回true
  3. value
    1. 迭代器返回的任何 JavaScript 值。done 为 true 时,则返回undifine

 

2,迭代器 案列

  • 创建一个对数组进行遍历的数据结构
function createArrayIterator(arr) {
  let index = 0
  return {
    next: function() {
      if (index < arr.length) {
        return { done: false, value: arr[index++] }
      } else {
        return { done: true, value: undefined } 
      }
    }
  }
}
const names = ["abc", "cba", "nba"]
const namesIterator = createArrayIterator(names)
console.log(namesIterator.next())
console.log(namesIterator.next())
console.log(namesIterator.next())
//{ done: false, value: 'abc' }
//{ done: false, value: 'cba' }
//{ done: false, value: 'nba' }
  •  创建一个无限的迭代器
// 创建一个无限的迭代器
function createNumberIterator() {
  let index = 0
  return {
    next: function() {
      return { done: false, value: index++ }
    }
  }
}
const numberInterator = createNumberIterator()
console.log(numberInterator.next())
console.log(numberInterator.next())
console.log(numberInterator.next())
console.log(numberInterator.next())
//{ done: false, value: 0 }
//{ done: false, value: 1 }
//{ done: false, value: 2 }
//{ done: false, value: 3 }
//{ done: false, value: 4 }

 3,可迭代对象

  • 但是上面的代码看起来会有点怪
    • 我们获取一个数组的时候,需要自己创建一个index变量,再创建一个所谓的迭代器对象
    • 事实上我们可以对上面的代码进行进一步的封装,让其变成一个可迭代对象
  • 什么又是可迭代对象呢
    • 它和迭代器是不同的概念;
    • 当一个对象实现了iterable protocol协议时,它就是一个可迭代对象
    • 这个对象的要求是必须实现 @@iterator 方法,在代码中我们使用 Symbol.iterator 访问该属性
    • 当我们要问一个问题,我们转成这样的一个东西有什么好处呢?
      • 当一个对象变成一个可迭代对象的时候,进行某些迭代操作,比如 for...of 操作时,其实就会调用它的 @@iterator 方法
  • 代码案列
    • 建一个迭代器对象来访问数组

const iterableObj = {
  names: ["abc", "cba", "nba"],
  [Symbol.iterator]: function() {
    let index = 0
    return {
      next: () => {
        if (index < this.names.length) {
          return { done: false, value: this.names[index++] }
        } else {
          return { done: true, value: undefined }
        }
      }
    }
  }
}
// iterableObj对象就是一个可迭代对象
// console.log(iterableObj[Symbol.iterator])

// 1.第一次调用iterableObj[Symbol.iterator]函数
// const iterator = iterableObj[Symbol.iterator]()
// console.log(iterator.next())
// console.log(iterator.next())
// console.log(iterator.next())
// console.log(iterator.next())


// 2.for...of可以遍历的东西必须是一个可迭代对象

for (const item of iterableObj) {
  console.log(item)
}
  •  原生迭代器对象
    • 事实上我们平时创建的很多原生对象已经实现了可迭代协议,会生成一个迭代器对象的
      • String、Array、Map、Set、arguments对象、NodeList集合;
const names = ["abc", "cba", "nba"]
console.log(names[Symbol.iterator])
const iterator1 = names[Symbol.iterator]() //[Function: values]
console.log(iterator1.next())
console.log(iterator1.next())
console.log(iterator1.next())
console.log(iterator1.next())
//{ value: 'abc', done: false }
//{ value: 'cba', done: false }
//{ value: 'nba', done: false }
//{ value: undefined, done: true }

for (const item of names) {
  console.log(item)
}
//
abc
cba
nba
//

// Map/Set
const set = new Set()
set.add(10)
set.add(100)
set.add(1000)

console.log(set[Symbol.iterator])

for (const item of set) {
  console.log(item)
}

// 函数中arguments也是一个可迭代对象
function foo(x, y, z) {
  console.log(arguments[Symbol.iterator])
  for (const arg of arguments) {
    console.log(arg)
  }
}

foo(10, 20, 30)
  • 可迭代对象的应用
    • JavaScript中语法:for ...of、展开语法、yield*、解构赋值
    • 创建一些对象时:new Map([Iterable])、new WeakMap([iterable])、new Set([iterable])、new WeakSet([iterable])
    • 一些方法的调用:Promise.all(iterable)、Promise.race(iterable)、Array.from(iterable);
      // 1.for of场景
      
      // 2.展开语法(spread syntax)
      const iterableObj = {
        names: ["abc", "cba", "nba"],
        [Symbol.iterator]: function() {
          let index = 0
          return {
            next: () => {
              if (index < this.names.length) {
                return { done: false, value: this.names[index++] }
              } else {
                return { done: true, value: undefined }
              }
            }
          }
        }
      }
      
      const names = ["abc", "cba", "nba"]
      const newNames = [...names, ...iterableObj]
      console.log(newNames)
      
      const obj = { name: "why", age: 18 }
      // for (const item of obj) {
      
      // }
      // ES9(ES2018)中新增的一个特性: 用的不是迭代器
      const newObj = { ...obj }
      console.log(newObj)
      
      
      // 3.解构语法
      const [ name1, name2 ] = names
      // const { name, age } = obj 不一样ES9新增的特性
      
      // 4.创建一些其他对象时
      const set1 = new Set(iterableObj)
      const set2 = new Set(names)
      
      const arr1 = Array.from(iterableObj)
      
      // 5.Promise.all
      Promise.all(iterableObj).then(res => {
        console.log(res)
      })

   4,自定义类的迭代

  • 在前面我们看到Array、Set、String、Map等类创建出来的对象都是可迭代对象
    • 在面向对象开发中,我们可以通过class定义一个自己的类,这个类可以创建很多的对象
    • 如果我们也希望自己的类创建出来的对象默认是可迭代的,那么在设计类的时候我们就可以添加上 @@iterator 方法
  • // 案例: 创建一个教室类, 创建出来的对象都是可迭代对象
    class Classroom {
      constructor(address, name, students) {
        this.address = address
        this.name = name
        this.students = students
      }
    
      entry(newStudent) {
        this.students.push(newStudent)
      }
    
      [Symbol.iterator]() {
        let index = 0
        return {
          next: () => {
            if (index < this.students.length) {
              return { done: false, value: this.students[index++] }
            } else {
              return { done: true, value: undefined }
            }
          },
          return: () => {
            console.log("迭代器提前终止了~")
            return { done: true, value: undefined }
          }
        }
      }
    }
    
    const classroom = new Classroom("3幢5楼205", "计算机教室", ["james", "kobe", "curry", "why"])
    classroom.entry("lilei")
    
    for (const stu of classroom) {
      console.log(stu)
      if (stu === "why") break
    }

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值