看了網上的一些資料,發現你們都寫得太複雜,讓新手難以入門。因而寫了這個極簡版的Underscore源碼閱讀。git
源碼:github
(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));
(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
(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了。函數
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; };