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