JS Iterator & Generator

132 阅读2分钟

Iterator & Generator

一、Iterator(迭代器)

1.Iterator

  • iterator 作为内置接口,只要数据结构部署了Iterator,皆可以进行遍历操作,依次处理item。
  • 原生带有Iterator的接口的数据结构:(可遍历)
    • Array、Map、Set、String、TypedArray(定型数组)、arguments(函数的参数对象)、NodeList(DOM节点对象)、WeakMap(), WeakSet(),其中arguments、NodeList为伪数组

[伪数组][juejin.cn/post/709086…]

  • Iterator 接口部署在数据结构的Symbol.iterator属性
  • 本质
    • 通过next()来移动指向成员的指针;
    • 每次执行next(),都会有一个返回值,要么返回迭代中的下一个成员,要么返回一个异常终止迭代;
    • next()返回一个对象,具有valuedone两个属性:
      value:返回当前位置的成员:
      done :一个布尔值,表示迭代是否结束

2. for ... of

创建一个循环来迭代可迭代的对象。在ES6中,使用for...of 来代替 for...in 和forEach

//数组
let _arr = [1,2,3,4,5,6,7,8]
for (let i of _arr){
console.log(i)
}
//map
let _map = new Map([['foo','fooValue'],['bar','barValue']])
for (let i of _map){
console.log(i)
}
//Set
let _set = new Set([20,52,20,90,80,50,80])
for (let i of _set){
console.log(i)
}
//string
let _str = "javaScript"
for (let i of _str){
console.log(i)
}
//arguments
function show() {
for (let i of arguments){
 console.log(i)
}
}
show("1","2","hello")
//obj转化
let _obj = { 0: 'foo', 1: 'bar', 2: 'baz' }
_obj.length = 3
//**let _objArray = Array.from(_obj) or **两种方法皆可以转化
let _objArray = Array.prototype.slice.call(_obj);
for (let value of _objArray) {
console.log(value);
}

for...in 循环将遍历对象的所有可枚举属性。
for...of 用来迭代任何具有 Symbol.iterator 属性的元素

Array.prototype.newArrFn = () => {};
Array.prototype.newArrFn2 = () => {};
const array = ['foo', 'bar', 'baz'];
for (let value in array) {
  console.log(value);
}
for (let value of array) {
  console.log(value);
}

1651118245(1).png

二、Genetator(生成器)

1.yield

让生成器函数暂定挂起,yield后面的表达式的值返回给生成器的调用者,有点类似return。与iterator类型,其返回值是一个对象,包含两个参数valuedone
value:返回值
done:一个布尔值,是否完成。

2.基本使用

function* add() {
  console.log(123)
 let x = yield 200
 console.log('hhhhh' + x)
 let y = yield  300
 console.log('ttttt' + y)
 yield 'foo'
 console.log(x+y)
 return x*2
}
let fn = add()
console.log(fn.next())
console.log(fn.next(20))
console.log(fn.next(30))
console.log(fn.next())

1651125426(1).png

  • 分段执行,yield表示暂停,调用next()继续执行
  • next()执行到返回下一次yield后面的参数返回,返回给调用者
  • next 的参数会通过yield传回函数内部
  • return 结束执行
  • 括号中的yield的优先级更高

3.this指向

首先回顾一下正常构造函数的this:

function user(name) {
   this.name = name
  console.log(this)
}
const _u = new user("wanwan")
  • new一个对象user,生成一个实例对象返回_u;
  • 将构造函数的this指向实例对象;
  • 将构造函数的原型对象赋值给实例对象的原型 (user.prototype == _u.proto) => true;
  • 再执行构造函数中的代码;
function* thisGeneratorFn() {
 console.log(this)
 yield 2
 return "hello"
}
thisGeneratorFn.prototype.sayHi =function(){
 console.log("hi")
}
let fn = thisGeneratorFn()
fn.sayHi()
console.log(fn.next())
console.log(fn.next())
console.log(fn)
console.log(thisGeneratorFn.prototype)
console.log(fn.__proto__)

1651127087(1).png