从函数定义中引用GeneratorFunction实例

时间:2017-04-04 22:50:19

标签: javascript node.js

我想在实例化的GeneratorFunction上设置属性。我希望能够将length属性设置为方便,因此消费者可以了解将生成多少个值。例如:

function* produceValues(someInput) {
    this.length = determineLength(someInput)
    yield // something
}

const gen = produceValues(input)
console.log(gen.length)

不出所料,使用this并不是指实例,而是指全局。 JavaScript是否提供了一些访问实例化对象的方法?

2 个答案:

答案 0 :(得分:1)

  

JavaScript是否提供了一些访问实例化对象的方法?

据我所知,不会更彻底地阅读规范 - 但总会有:

function* produceValues_(someInput) {
    yield determineLength(someInput);
}

function produceValues(someInput) {
    const gen = produceValues_(someInput);
    gen.length = gen.next();
    return gen;
}

答案 1 :(得分:1)

不,不幸的是,因为this适用于将生成器函数用作方法,而不是用作构造函数(它们是)。所以你能做的就是

function* _produceValues(someInput) {
    yield // something
}
function produceValues(someInput) {
    var res = _produceValues(someInput);
    res.input = someInput;
    // or res.length = …
    return res;
}
produceValues.prototype = Object.defineProperties(_produceValues.prototype, {
    length: {
        get() { return determineLength(this.input); }
    }
});

const gen = produceValues(input);
console.log(gen instanceof produceValues);
console.log(gen.input);
console.log(gen.length);

我们也可以给它一些疯狂的语法糖:

function generatorClass(genFun) {
    function constructor(...args) { return Object.setPrototypeOf(genFun(...args), new.target.prototype); }
    constructor.prototype = genFun.prototype;
    return constructor;
}
class produceValues extends generatorClass(function*(someInput) {
    yield // something
}) {
    constructor(someInput) {
        super(someInput);
        this.input = someInput;
    }
    get length() {
        return determineLength(this.input);
    }
}

但是你必须使用const gen = new produceValues(input)。虽然gen是一个具有额外属性的特殊生成器实例,但很明显。