Underscore源碼閱讀極簡版入門

看了網上的一些資料,發現你們都寫得太複雜,讓新手難以入門。因而寫了這個極簡版的Underscore源碼閱讀。git

源碼:github

github.com/hanzichi/un…bash

1、架構的實現

1.1:架構

(function(){
    var _={};
    this._=_;
}.call(this));
複製代碼

1.2:使用exports導出

引入exports判斷,若是不支持exports則繼續使用this架構

(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));
複製代碼

第一步就先這到這裏,接下來就是經常使用函數的包裝了。先不用管其餘函數。app

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了。 查看效果: codepen.io/walkingp/pe…ide

3、重要函數

optimizeCb

沒有太懂這裏Cb是什麼,多是Context bind,上下文綁定,其實主要就是使用call改變this到當前func上。函數

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函數

應該是context bind,就調用了上面的optimizeCb函數,若是是傳入的value是Function,就執行optimizeCb;若是是Object就直接matcher;不然_.property優化

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,就是每次調用後把實例返回回去。ui

_.chain = function(obj) {
  var instance = _(obj);
  instance._chain = true;
  return instance;
};
複製代碼

其餘

1.9.1中對root又進行了優化,多了判斷 github.com/jashkenas/u…this

var root = typeof self == 'object' && self.self === self && self ||
            typeof global == 'object' && global.global === global && global ||
            this ||
            {};
複製代碼
相關文章
相關標籤/搜索