javascript - underscore.js 源码问题
伊谢尔伦
伊谢尔伦 2017-04-11 09:46:08
[JavaScript讨论组]

在学习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);
    };
伊谢尔伦
伊谢尔伦

小伙看你根骨奇佳,潜力无限,来学PHP伐。

全部回复(2)
ringa_lee

这段代码不好说,简单来讲就是方法优化了,建议对照着后续代码里的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: 这种优化可读性不直观,但优化了代码,复用了代码,减少代码量~

天蓬老师

这个问题我就偷个懒了
@韩子迟 曾经写过一个完整的underscore源码解析,你直接去看带中文注释版的源码吧。
https://github.com/hanzichi/u...

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号