我可以将 属性 附加到使用 JavaScript 中的函数*() 创建的生成器吗?
Can I attach a property to a generator created with function*() in JavaScript?
我正在寻找一种方法来公开使用 function*()
构造的生成器的其他属性。我尝试了两种幼稚的方法,但都没有达到我想要的效果。
方法 1 说明了我正在尝试做的事情,天真地尝试使用 this
将 属性 附加到生成器:
function* counter(startValue) {
// trying to expose a property through "this",
// which does not work as intended
// (I actually expected this, but it illustrates what I am trying to do)
this.startValue = startValue;
// simple counter
let currentValue = startValue;
while (true) yield currentValue++;
}
// user code
let myCounter = counter(10);
console.log(myCounter.next().value);
// -> 10
console.log(myCounter.next().value);
// -> 11
// I want myCounter.startValue to expose the start value (10)
// unfortunately this does not work
console.log(myCounter.startValue);
// -> undefined
方法 2,尝试使用闭包来存储起始值:
// use a closure to store configuration & state
function counter(startValue) {
let currentValue = startValue;
let gen = function*() {
while(true) yield currentValue++;
}
// Again, I want the generator to expose the "startValue" parameter
// This also does not work:
gen.startValue = startValue;
return gen;
}
// user code
let myCounter = counter(10)();
myCounter.next().value;
// -> 10
myCounter.next().value;
// -> 11
// Again, no luck accessing the start value
myCounter.startValue;
// -> undefined
我想由于实际的生成器对象是由 JS 运行时隐式构造的,所以如果不创建某种包装对象就无法为其附加额外的属性?
(由于整个项目结构的原因,构建生成器然后附加 属性(myCounter.startValue = 10
在用户代码中的某处)对我来说不是一个选项,它必须完成在构造函数中)
你的关闭尝试是正确的方法,你只是错过了在函数内部创建生成器(你想附加 属性 ),而不是将它附加到生成器函数:
function* count(currentValue) {
while(true) yield currentValue++;
}
function counter(startValue) {
const gen = count(startValue);
gen.startValue = startValue;
return gen;
}
let myCounter = counter(10);
myCounter.next().value; // -> 10
myCounter.next().value; // -> 11
myCounter.startValue; // -> 10
正确的方法是通过它下面的实际内容来处理 ES6 生成器 - Iterable Iterator
,并这样实现它,添加你的扩展:
function counter(startValue) {
let currentValue = startValue;
return {
[Symbol.iterator]() {
return this;
},
next() {
return {value: currentValue++, done: false}
},
startValue
};
}
let myCounter = counter(10);
console.log(myCounter.next().value); //=> 10
console.log(myCounter.next().value); //=> 11
console.log(myCounter.startValue); //=> 10
这就是正确扩展生成器的方式。
我正在寻找一种方法来公开使用 function*()
构造的生成器的其他属性。我尝试了两种幼稚的方法,但都没有达到我想要的效果。
方法 1 说明了我正在尝试做的事情,天真地尝试使用 this
将 属性 附加到生成器:
function* counter(startValue) {
// trying to expose a property through "this",
// which does not work as intended
// (I actually expected this, but it illustrates what I am trying to do)
this.startValue = startValue;
// simple counter
let currentValue = startValue;
while (true) yield currentValue++;
}
// user code
let myCounter = counter(10);
console.log(myCounter.next().value);
// -> 10
console.log(myCounter.next().value);
// -> 11
// I want myCounter.startValue to expose the start value (10)
// unfortunately this does not work
console.log(myCounter.startValue);
// -> undefined
方法 2,尝试使用闭包来存储起始值:
// use a closure to store configuration & state
function counter(startValue) {
let currentValue = startValue;
let gen = function*() {
while(true) yield currentValue++;
}
// Again, I want the generator to expose the "startValue" parameter
// This also does not work:
gen.startValue = startValue;
return gen;
}
// user code
let myCounter = counter(10)();
myCounter.next().value;
// -> 10
myCounter.next().value;
// -> 11
// Again, no luck accessing the start value
myCounter.startValue;
// -> undefined
我想由于实际的生成器对象是由 JS 运行时隐式构造的,所以如果不创建某种包装对象就无法为其附加额外的属性?
(由于整个项目结构的原因,构建生成器然后附加 属性(myCounter.startValue = 10
在用户代码中的某处)对我来说不是一个选项,它必须完成在构造函数中)
你的关闭尝试是正确的方法,你只是错过了在函数内部创建生成器(你想附加 属性 ),而不是将它附加到生成器函数:
function* count(currentValue) {
while(true) yield currentValue++;
}
function counter(startValue) {
const gen = count(startValue);
gen.startValue = startValue;
return gen;
}
let myCounter = counter(10);
myCounter.next().value; // -> 10
myCounter.next().value; // -> 11
myCounter.startValue; // -> 10
正确的方法是通过它下面的实际内容来处理 ES6 生成器 - Iterable Iterator
,并这样实现它,添加你的扩展:
function counter(startValue) {
let currentValue = startValue;
return {
[Symbol.iterator]() {
return this;
},
next() {
return {value: currentValue++, done: false}
},
startValue
};
}
let myCounter = counter(10);
console.log(myCounter.next().value); //=> 10
console.log(myCounter.next().value); //=> 11
console.log(myCounter.startValue); //=> 10
这就是正确扩展生成器的方式。