Eva*_*oll 1 javascript iterable generator ecmascript-6
让我们假设一个具有已定义迭代器的对象的两个类似实现:一个使用生成器的迭代器,另一个使用迭代.这两个都可以使用Array.from,并且它们都可以迭代.这两种方法有哪些区别,哪一种更受欢迎,为什么?是否需要较小的方法?
class Foo {
constructor( ...args ) {
this.f = args;
}
[Symbol.iterator]() {
let c = 0;
const i = {
next: () => {
if ( c < this.f.length ) {
return {value:this.f[c++], done: false};
}
else {
return {value:undefined,done:true};
}
}
};
return i;
}
};
class Bar {
constructor( ...args ) {
this.f = args;
}
*[Symbol.iterator]() {
let c = 0;
if ( c < this.f.length ) {
yield this.f[c++];
}
else {
return;
}
}
};
Run Code Online (Sandbox Code Playgroud)
在这里,我们可以测试它们,以表明它们基本相同.
var o1 = new Foo([1,2,3]);
for ( let x of o1 ) {
console.warn(x)
}
console.log(o1, Array.from(o1));
var o2 = new Bar([1,2,3]);
for ( let x of o2 ) {
console.warn(x)
}
console.log(o2, Array.from(o2));
Run Code Online (Sandbox Code Playgroud)
具有已定义迭代器的对象的两个类似实现:一个使用生成器的迭代器,另一个使用迭代.
让我们首先纠正术语:你已经为Iterables定义了两个(构造函数)对象.它们都是可迭代的,因为它们有Symbol.iterator返回迭代器的next方法- 带有方法的对象.其中一种方法是通过字面返回一个对象来实现的,另一种是使用生成器语法实现的.
我们可以测试它们,以表明它们基本相同.
呃,不,你犯了一个根本性的错误:你在构造函数中使用了rest参数,因此你的两个对象都以一个数组的数组作为它们的f值.
如果您使用了var o = new FooBar(1, 2, 3)或者constructor(args) {,该属性将是您所期望的,并且示例将表明它们绝对不会做同样的事情.
所以让我们修复你的代码:
class Test {
constructor(arr) {
this.f = arr;
}
}
class Foo extends Test {
[Symbol.iterator]() {
let c = 0;
return {
next: () => {
if ( c < this.f.length ) {
return {value: this.f[c++], done: false};
} else {
return {value: undefined, done: true};
}
}
};
}
}
class Bar extends Test {
*[Symbol.iterator]() {
let c = 0;
while (c < this.f.length) // written a lot nicer using a `for` loop
yield this.f[c++];
// return undefined; // we really should omit that
}
}
for (let test of [Foo, Bar]) {
console.log(test.name);
const o = new test([1,2,3]);
for (const x of o)
console.log(x)
console.log(Array.from(o));
}Run Code Online (Sandbox Code Playgroud)
这现在做你真正想要的.
这两种方法有什么不同?
我希望从上面的代码中可以清楚地看出:生成器函数更加简单.
哪个是首选,为什么?
猜测:-)语法糖通过抽象提高可读性并简化复杂的行为.
是否需要较小的方法?
我无法想象任何标准用例.当然,生成器语法是引擎需要支持的功能,但完整的迭代协议也是如此.也许有一些边缘情况,手工制作的微优化迭代器对象比生成器更快/更便宜/更轻,例如对于恒定的无限迭代器,但我对此表示怀疑.