js生成器generator

2021-02-02  本文已影响0人  攻城熊

有了上篇文章迭代器的基础, 这篇文章才意义.

生成器对象

function* gen() {
  yield 1;
  yield;
  yield 3;
}
let g = gen();

生成器对象是由一个 generator function 返回的,并且它符合可迭代协议迭代器协议

g.next();  // {value: 1, done: false}
g.next();  // {value: undefined, done: false}
g.next();  // {value: 3, done: true}
image.png

通过打印,我们可以观察到一个生成器对象中包含三个函数,next() return() throw()

next()我们已经熟悉了
Generator.prototype.next()
返回一个由 yield表达式生成的值。

return() 方法返回给定的值并结束生成器。
gen.return(value)

throw() 向生成器抛出一个错误。

generator函数中的this问题

// 正常函数
function F () {
  this.a = 1
}
const f = new F()
// 调用构造函数F,返回实例对象f
// 将构造函数内部中的this指向这个实例对象
// 将构造函数中的原型对象赋值给实例对象的原型
// 执行构造函数中的代码

// 调用Generator函数会返回遍历器对象,而不是实例对象,因此无法获取到this指向的实例对象上的私有属性和方法。但是这个遍历器对象可以继承Generator函数的prototype原型对象上的属性和方法(公有属性和方法)。
function* g() {}

g.prototype.hello = function () {
  return 'hi!';
};

let obj = g();

obj instanceof g // true
obj.hello() // 'hi!'

上面代码表明,Generator 函数g返回的遍历器obj,是g的实例,而且继承了g.prototype。但是,如果把g当作普通的构造函数,并不会生效,因为g返回的总是遍历器对象,而不是this对象。

应用generator 数组扁平化

function* flatten3(arr) {
    let length = arr.length;
    for (let i=0; i<length; i++) {
        let item = arr[i];
        if (Array.isArray(item)) {
            yield* flatten3(item);
        } else {
            yield item;
        }
    }
} 

let res = [];
for (let f of flatten3 (arr)) {
    res.push(f);
}
console.log(res)

迭代方法

function flatten2(arr) {
  const stack = [...arr];
  const res = [];
  while (stack.length) {
    // 从栈里取出
    const next = stack.pop();
    if (Array.isArray(next)) {
      // 把next扁平化,然后放入stack中
      stack.push(...next);
    } else {
      res.push(next);
    }
  }
  // reverse to restore input order
  return res.reverse();
}
console.log(flatten2(arr))
上一篇 下一篇

猜你喜欢

热点阅读