Underscore源码阅读极简版入门

看了网上的一些资料,发现你们都写得太复杂,让新手难以入门。因而写了这个极简版的Underscore源码阅读。git

源码:github

https://github.com/hanzichi/underscore-analysis/blob/master/underscore-1.8.3.js/src/underscore-1.8.3.js架构

 

1、架构的实现

1.1:架构

(function(){
    var _={};
    this._=_;
}.call(this));

1.2:引入exports判断,若是不支持exports则继续使用thisapp

(function(){
  var root = this;
  var _={};if (typeof exports !== 'undefined') {
    if (typeof module !== 'undefined' && module.exports) {
      exports = module.exports = _;
    }
    exports._ = _;
  } else {
    root._ = _;
  }
}.call(this));

1.3:对_进行进一步实例化判断: 

(function(){
  var root = this;
  var previousUnderscore = root._;//保存_
  //初始化
  var _=function(obj){
    if(obj instanceof _) return obj;
    if(!(this instanceof _)) return new _(obj);
    this._wrapped=obj;//保存obj
  };
  //导出_
  if (typeof exports !== 'undefined') {
    if (typeof module !== 'undefined' && module.exports) {
      exports = module.exports = _;
    }
    exports._ = _;
  } else {
    root._ = _;
  }
}.call(this));

第一步就先这到这里,接下来就是经常使用函数的包装了。先不用管其余函数。ide

2、经常使用函数包装

(function(){
  var root = this;
  var previousUnderscore = root._;//保存_
  //初始化
  var _=function(obj){
    if(obj instanceof _) return obj;
    if(!(this instanceof _)) return new _(obj);
    this._wrapped=obj;//保存obj
  };
  //导出_
  if (typeof exports !== 'undefined') {
    if (typeof module !== 'undefined' && module.exports) {
      exports = module.exports = _;
    }
    exports._ = _;
  } else {
    root._ = _;
  }

 //添加判断Boolean类型方法
  _.isBoolean = function(obj) {
    return obj === true || obj === false || toString.call(obj) === '[object Boolean]';
  };
}.call(this));

恭喜你,接下来就能够直接使用_.isBoolean了。函数

3、重要函数

optimizeCb,没有太懂这里Cb是什么,多是Context bound,上下文绑定,其实主要就是使用call改变this到当前func上。this

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

cb函数就调用了上面的函数,若是是传入的value是Function,就执行optimizeCb;若是是Object就直接matcher;不然_.propertyspa

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

链式调用chain,相似jQuery的反复调用code

_.chain = function(obj) {
  var instance = _(obj);
  instance._chain = true;
  return instance;
};
相关文章
相关标签/搜索