gpt4 book ai didi

javascript - 下划线js中的优化Cb如何工作?

转载 作者:行者123 更新时间:2023-11-29 14:43:00 25 4
gpt4 key购买 nike

我一直在考虑这个,来自 underscorejs :

  var optimizeCb = 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);
};
};

因此,显然此优化仅适用于设置 this 值(此处称为 context)的回调。这与直接对回调调用 call 有何不同?这如何能够提高性能?

如果优化只对遗留 JS 引擎有效,那也没关系。我非常想知道。

编辑

我可能在问题中不清楚。这就是我的意思。让我们以使用 optimizeCb 为例:

  _.each = _.forEach = function(obj, iteratee, context) {
iteratee = optimizeCb(iteratee, context); //REMOVE this
var i, length;
if (isArrayLike(obj)) {
for (i = 0, length = obj.length; i < length; i++) {
iteratee(obj[i], i, obj);
//REPLACE with iteratee.call(context, obj[i], i, obj);
}
} else {
var keys = _.keys(obj);
for (i = 0, length = keys.length; i < length; i++) {
iteratee(obj[keys[i]], keys[i], obj);
}
}
return obj;
};

查看 2 条评论:iteratee = optimizeCb(iteratee, context);//删除这个iteratee(obj[i], i, obj);//替换为 iteratee.call(context, obj[i], i, obj);。我知道 arguments 很慢,apply 很慢。但我看不出argumentscall vs apply 在这里发挥作用?我看不出这两种方法有什么区别。

我认为关键问题是,如果将回调传递给某个下划线方法,那么签名是已知的。例如,传递给 _.each 的回调必须具有 function(value, index, collection)。调用 optimizeCb 的方式证实了这一观察:如果 optimizeCb 的调用者能够提供 argCount 参数(留空意味着它是 3),它知道它是哪个签名。

有人可以进一步详细说明吗?非常感谢!

最佳答案

他们可能这样做的三个原因:

  1. 访问 arguments 伪数组在旧的 JavaScript 引擎上成本很高。真的很费钱。就像,几个数量级的成本。 :-)

    我认为现代引擎不再有巨大的成本,尤其是在严格模式下,它删除了 arguments 和形式函数参数之间的实时链接。

  2. 作为Moogscomment 中指出, applycall 慢。基于this test ,看起来介于成本的一半和两倍之间。因此,与 arguments(过去)的数量级或两个数量级不同,但仍然更快。

  3. 如果 contextundefined,它们返回函数不变(这是初始的 if (context == void 0) return func;), 所以调用它时根本不涉及 .call .apply

所以它的作用是双重的:

A) 如果回调不需要特定的 this,它会直接通过简单的函数调用来使用回调。如果回调确实需要特定的this,他们会创建一个可以调用的函数,使用正确的this,这样可以节省传递围绕 context 参数并简化调用代码。

B) 他们通过定制包装函数避免访问arguments 和使用apply 用于常见数量的参数:采用 1-4 个参数的回调可以避免成本,具有 0 个或超过 4 个参数的回调会产生成本。

关于javascript - 下划线js中的优化Cb如何工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36162941/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com