es6 生成器函数里面 yield *this.items.keys(); 中的 *this 什么作用

发布于 2022-09-06 11:43:40 字数 2110 浏览 27 评论 0

深入理解es6 p146,看到一串代码:
代码前的引言:

既然生成器方法很有用,那么在表示集合的自定义类中定义一个默认迭代器,那就更好。你可以使用 Symbol.iterator 来定义生成器方法,从而定义出类的默认迭代器,就像这样:
class Collection {
    constructor() {
            this.items = [];
        }
        *[Symbol.iterator]() {
            yield *this.items.keys();
        }
}
var collection = new Collection();
collection.items.push(1);
collection.items.push(3);
collection.items.push(2);

for (let x of collection) {
    console.log(x);
}

全书 *this 用法只此一处,这个地方我不明白,这是什么用法?我测试了下, *this 的代码可以这样替换:

class Collection {
    constructor() {
            this.items = [];
        }
        *[Symbol.iterator]() {
            for (let item of this.items.keys()) {
                yield item;
            }
        }
}
var collection = new Collection();
collection.items.push(1);
collection.items.push(3);
collection.items.push(2);

for (let x of collection) {
    console.log(x);
}

如果* this 代码不改,换一种实现方式也可以

class Collection {
    constructor() {
            this.items = [];
        }
        *[Symbol.iterator]() {
            yield *this.items.keys();
        }
}
var collection = new Collection();
collection.items.push(1);
collection.items.push(3);
collection.items.push(2);

/*for (let x of collection) {
    console.log(x);
}*/

for (let x of collection.items.keys()) {
    console.log(x);
}

但是我始终不能理解这个用法是为什么,因为我觉得没有 * 也是可以的,但是实际上测试没有 * 就不对了,于是我就猜测,难道这里是这么个意思?把 this.items.keys 当成生成器函数?但是觉得不合理

class Collection {
    constructor() {
            this.items = [];
        }
        *[Symbol.iterator]() {
            yield *(this.items.keys)();
        }
}
var collection = new Collection();
collection.items.push(1);
collection.items.push(3);
collection.items.push(2);

for (let x of collection) {
    console.log(x);
}

所以有人知道这里的 *this 到底是什么逻辑么?
书上这么解释的

此例为生成器方法使用了一个需计算名称,并将此方法委托到 this.items 数组的 keys()
迭代器上。任意管理集合的类都包含一个默认迭代器,这是因为一些集合专用的操作都要求
目标集合具有迭代器。现在, Collection 的任意实例都可以在 for-of 循环内被直接使
用,也能配合扩展运算符使用。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

↘人皮目录ツ 2022-09-13 11:43:40

yield *是一个表达式,是用来在一个生成器函数里执行另一个生成器函数的。

以你第一个代码为例:

class Collection {
    constructor() {
            this.items = [];
        }
        *[Symbol.iterator]() {
            yield *this.items.keys();
        }
}
var collection = new Collection();
collection.items.push(1);
collection.items.push(3);
collection.items.push(2);

for (let x of collection) {
    console.log(x);
}

for (let x of collection) {}
等价于
for (let x of collection.[Symbol.iterator]()) {}
等价于
for (let x of collection.items.keys()) {}

贴个详细地址

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文