i我试图过滤发电机,并希望必须在JavaScript中的任何地方定义这种一般功能,因为它是为数组定义的,但是我找不到它。所以我试图定义它。但是我无法扩展内置的发电机。 我有一个示例生成器
function make_nums ()
{
let nums = {};
nums[Symbol.iterator] = function* () {
yield 1;
yield 2;
yield 3;
};
return nums;
}
加快了一些数字
[...make_nums()] // => Array [ 1, 2, 3 ]
如果我构建一个数组,我可以通过使用
filter
函数来过滤数组。
[...make_nums()].filter(n => n > 1) // => Array [ 2, 3 ]
但我不想构建一个数组。取而代之的是,我想带上旧的发电机并构建一个新的过滤发生器。为此,我写了以下功能。
function filtered (generator, filter)
{
let g = {};
g[Symbol.iterator] = function* () {
for (let value of generator)
if (filter(value))
yield value;
};
return g;
}
可以用来做我想做的事。
[...filtered (make_nums(), n => n > 1)] // => Array [ 2, 3 ]
但这是一个非常通用的函数,可以以相同的方式应用于每个发电机的函数,可以应用于每个发电机的函数。因此,我试图扩展发电机,但我不明白如何。为
发电机的MDN文档表明可能存在
filter
可能存在,但似乎不存在。当我尝试在
Array
中定义某些内容时,我会得到错误
ReferenceError:未定义生成器 我如何扩展内置的
Generator.prototype
类?
获得发电机函数原型
Generator.prototype
您可以添加一个功能:
Generator
因此:
const genproto = Object.getPrototypeOf(function*(){});
filter()
.
要清楚:这个答案是关于扩展发电机函数的原型,而不是生成器对象本身。因此,这将确保程序中的每个发电机函数都可以使用该方法和任何其他类似的扩展名。
事实证明,我对
Object.defineProperty(genproto, "filter", {
value: function*(predicate) {
for (let value of this())
if (predicate(value)) yield value;
}
});
和console.log([... function*() {
for (let i = 0; i < 10; i++) yield i;
}.filter(value => value % 2 === 0)
]);
感到困惑。我以为我必须扩展[0, 2, 4, 6, 8]
.filter()
。 Generator
似乎也没有由JavaScript定义,这一事实使其很容易定义它,以避免使用内置原型进行修改的问题。这实际上会做我试图实现的目标。
Iterable
我可以创建Generator
Iterable
Iterable
可以过滤
class Iterable {
constructor (generator) {
this[Symbol.iterator] = generator;
}
}
Iterable.prototype.filter = function (predicate) {
let iterable = this;
return new Iterable (function* () {
for (let value of iterable)
if (predicate (value))
yield value;
});
};
自这个问题发布以来,已经过去了。同时,Ecmascript 2025在Iterables
上定义了make_nums = new Iterable(function* () { yield 1; yield 2; yield 3; });
构造器(摘要)和[...make_nums] // => Array [ 1, 2, 3 ]
方法,因此滤波了由Core JS功能(例如生成器函数)返回的迭代器,从而出现了:
[...make_nums.filter(n => n > 1)] // => Array [ 2, 3 ]