underscore源码阅读整理

underscore是我阅读的第一份源码,这份代码比较小巧,只有1500行,我阅读的版本是1.8.3.underscore里封装了很多功能性的函数,和jQuery不同,我觉得jQuery的特点是对针对DOM,而underscore里都是基于JS的功能性函数,比如each,map等等。
以下内容仅是我阅读过程中记录的笔记,可能会有错误或理解不到位的地方。。。

整体结构

underscore中:

(function(){
    var root = this;
    var previousUnderscore = root._;
    var _ = function(obj) {
        if (obj instanceof _) return obj;
        if (!(this instanceof _)) return new _(obj);
        this._wrapped = obj;
      };
}).call(this);
  1. 最外层是个立即执行函数,用call函数把this传进去,我认为因为underscore既可以运行在浏览器端又可以运行在服务器端,所以它传入的是this,而不是像jQuery一样直接传进去window
  2. 这里有几个比较重要的地方:
    1. 像jQuery注册在$上一样,underscore注册在’‘上,而且为了避免冲突都会先保存一下之前的root.
    2. ‘_’其实是一个函数,如果传入的是’_’的实例则直接返回,如果不是则new一个出来,并把它放到_wrapped属性中。举个例子:
 _([1,2,3]) ==》 Object{_wrapped:[1,2,3], _proto_:Object} //其中_proto_上有所有的方法

jQuery中:

(function(window, undefined) {

})(window);

jQuery中是直接指定了this=window

几个重要的公共方法

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

  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);
  };
  • optimizeCb函数的传入参数只能是function,根据传入的参数不同返回不同的合理的回调函数
  • cb函数一般用来处理作为迭代器的函数,传入的value可以是函数、object或者property,但是返回的一定会是函数
var createAssigner = function(keysFunc, undefinedOnly) {
    return function(obj) {
      var length = arguments.length;
      if (length < 2 || obj == null) return obj;
      for (var index = 1; index < length; index++) {
        var source = arguments[index],
            keys = keysFunc(source),
            l = keys.length;
        for (var i = 0; i < l; i++) {
          var key = keys[i];
          if (!undefinedOnly || obj[key] === void 0) obj[key] = source[key];
        }
      }
      return obj;
    };
  };
  • _.extend和 _.extendAll其实就是调用这个函数实现的,所以他的功能就是扩展object
  • 这里传入的参数keysFunc是用来取用于扩展的keys,因为传入的是_.keys和 _.allKeys两种决定了是否可以拿到!hasOwnProperty的属性
  • 这里undefinedOnly的作用我也不太理解,源码中调用这个函数的时候从来没有传入过undefinedOnly这个参数。。。。
  var baseCreate = function(prototype) {
    if (!_.isObject(prototype)) return {};
    if (nativeCreate) return nativeCreate(prototype);
    Ctor.prototype = prototype;
    var result = new Ctor;
    Ctor.prototype = null;
    return result;
  };
  • 用于继承的函数,其实就是ES5的Object.create
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值