Underscore.js包含了回调效率

时间:2014-11-05 14:17:40

标签: javascript performance underscore.js

我对annotated underscore.js source code

有疑问

它说:

  

内部函数,返回传入回调的高效(当前引擎)版本,并在其他Underscore函数中重复应用。

var createCallback = function(func, context, argCount) {
    if (context === void 0) return func;
    switch (argCount == null ? 3 : argCount) {
        case 1: return function(value) {
            return func.call(context, value);
        };
        case 2: return function(value, other) {
            return func.call(context, value, other);
        };
        case 3: return function(value, index, collection) {
            return func.call(context, value, index, collection);
        };
        case 4: return function(accumulator, value, index, collection) {
            return func.call(context, accumulator, value, index, collection);
        };
    }
    return function() {
        return func.apply(context, arguments);
    };
};

明确地说,如何在这段代码中达到效率?

因为我看到使用包装器,创建了一个更多级别的间接,并且范围链再增加了一个级别。

我需要了解如何达到效率,以便在我自己的js中应用这些技巧。

谢谢!

2 个答案:

答案 0 :(得分:1)

似乎有一些参数顺序的混乱,但如果后来的参数留空,有些情况实际上是等价的。我认为这种逻辑也可能使得回调在浏览器优化方面发挥得很好。例如,如果返回值是可预测的,则结果可以内联而不是每次调用实际函数。 以下是关于性能和参数的相关讨论,其中测试显示出一些巨大的速度差异:

Performance penalty for undefined arguments

答案 1 :(得分:0)

使用下划线迭代器函数(例如_.map_.reduce_.each)时,提供的回调提供不同的参数。例如:

_.map(list, function(value, key, list) {});

_.reduce(list, function(memo, num, list) {});

createCallback是一个便捷函数,由下划线在内部用来定义这些迭代器函数中参数的顺序。如果我们查看_.reduce函数,我们可以看到这一行:

iteratee = createCallback(iteratee, context, 4);

将输出:

func.call(context, accumulator, value, index, collection);

其中func是提供给_.reduce

的迭代器函数