在JavaScript中,' eval '是创建具有动态确定属性的函数的唯一方法吗?

Is `eval` the only way to create functions with dynamically determined arity in JavaScript?

本文关键字:属性 函数 唯一 方法 JavaScript eval 创建 动态      更新时间:2023-09-26

我正在使用JavaScript间谍库,simple-spy .

我发现当监视一个给定的函数时,生成的spy的值始终为0。

这造成了我使用的问题这个套用函数

所以我已经提交了一个pull-request这增加了透明度间谍库。

代码如下:

function spy(fn) {
    const inner = (...args) => {
        stub.callCount++;
        stub.args.push(args);
        return fn(...args);
    };
    // ends up a string like
    // 'a,b,c,d'
    // depending on the `fn.length`
    const stubArgs = Array(fn.length)
        .fill(null)
        .map((m, i) => String.fromCodePoint(97 + i))
        .join();
    const stubBody = 'return inner(...arguments);';
    // this seems to be the only way
    // to create a function with
    // programmatically specified arity
    const stub = eval(
        // the wrapping parens is to
        // prevent it from evaluating as
        // a function declaration
        `(function (${stubArgs}) { ${stubBody} })`
    );
    stub.reset = () => {
        stub.callCount = 0;
        stub.args = [];
    };
    stub.reset();
    return stub;
}
exports.spy = spy;

这似乎可以工作。

这是可能的吗不使用eval ?

有可能减少eval的使用甚至比这个更少?

我知道还有其他问题使用这个间谍实现。这很简单,但很有效对于我目前的用例

就像Benjamin写的那样,我使用了一个简单的:

function spy(fn) {
    const stub = (...args) => {
        stub.callCount++;
        stub.args.push(args);
        return fn(...args);
    };
    stub.reset = () => {
        stub.callCount = 0;
        stub.args = [];
    };
    stub.reset();
    Object.defineProperty(stub, 'length', {value: fn.length});
    return stub;
}
exports.spy = spy;

好看多了