`eval`是在JavaScript中用动态确定的arity创建函数的唯一方法吗?

时间:2016-10-28 21:42:24

标签: javascript function dynamic eval arity

我使用的是JavaScript间谍程序库, simple-spy

我发现在监视特定功能时, 由此产生的间谍总是有一个arity为0。

这会导致我使用的问题 this currying function

所以我submitted a pull-request that adds arity transparency to the spy library

代码如下所示:

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的使用 甚至更少这个?

我知道还有其他问题 这个间谍实施。 它很简单,而且很有效 至于我的用例到目前为止。

1 个答案:

答案 0 :(得分:2)

就像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;

看起来好多了。