javascript - underscore.js 源码问题

查看:109
本文介绍了javascript - underscore.js 源码问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问 题

在学习js呢,研究underscore.js源码,但是有些地方不太明白,希望有大神指导一二。比如,下面这段代码是干嘛用的呢?

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

    // A mostly-internal function to generate callbacks that can be applied
    // to each element in a collection, returning the desired result 鈥� either
    // identity, an arbitrary callback, a property matcher, or a property accessor.
    var cb = function(value, context, argCount) {
        if (value == null) return _.identity;
        if (_.isFunction(value)) return optimizeCb(value, context, argCount);
        if (_.isObject(value)) return _.matcher(value);
        return _.property(value);
    };

解决方案

这段代码不好说,简单来讲就是方法优化了,建议对照着后续代码里的api实现来走读这段代码

比如我们看each方法:

_.each = _.forEach = function(obj, iteratee, context) {
    iteratee = optimizeCb(iteratee, context);//这里就用到了optimizeCb
    var i, length;
    if (isArrayLike(obj)) {
      for (i = 0, length = obj.length; i < length; i++) {
        iteratee(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;
  };

我们知道each方法参数一般只传两个,但传第三个时,第二个function会绑定到第三个参数的作用域上。

如果只传两个的话,实际上在调用optimizeCb时,只是return func而已了。

但如果传三个参数的话,optimizeCb的执行会执行到:

return function(value, index, collection) {
                return func.call(context, value, index, collection);
            };

也就是说这时候optimizeCb返回的是一个新的function,这个function如果被调用的话,实际上就是给回调func绑定了context作用域了。

其他switch,按不同的方法去走读,就差不多知道个大概了~

ps: 这种优化可读性不直观,但优化了代码,复用了代码,减少代码量~

这篇关于javascript - underscore.js 源码问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆