CNode

最近在看 underscore.js 的代码,一个函数 optimizeCb 无法理解

问答
Ddd1994发布于11 年前最后回复10 年前3 回复6333 浏览0 收藏

就是这个 optimizeCb 函数,这是个独立的,在 underscore 里面非常基础的函数,后面的函数里经常用到它,

我直接把它贴上来吧

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);
    };
  };

文档介绍它说是

Internal function that returns an efficient (for current engines) version of the passed-in callback, to be repeatedly applied in other Underscore functions.

为什么这个函数可以返回一个 efficient version 呢?

查看回复

回复 (3)

C
chapgaga#1·11 年前

楼主除了它,还看过什么库呢?

G
ghostcode#2·10 年前

上面一大段 switch 是为了在已知参数数量的情况下让 js 引擎做出优化(避免使用 arguments)。

等价如下:

var optimizeCb = function(func, context, argCount) {
    return function() {
        return func.apply(context, arguments);
    };
};

类似bind的功能。 https://www.zhihu.com/question/31439403

F
flamingtop#3·10 年前

就是把调用的context(母对象)显式化。 比如 window.open 比 open 效率稍高。 因为,解释器看到window.open不需要自己去解析open是在哪个母对象执行的,一层层往上追溯损失效率。 现在为了open的简洁,而又不想失去这一点效率,就 var open = optimizeCB(open, window, ..)

下面的代码就可以痛快地 open(...) open(...) open(...) 了。

当同一函数调用次数多的时候(比如底层函数),这个优化还是有意义的。

参与回复
登录后即可参与回复。登录