• Underscore源码阅读极简版入门


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

    源码:

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

    一、架构的实现

    1.1:架构

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

    1.2:引入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));

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

    二、常用函数包装

    (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上。

    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;否则_.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的反复调用

    _.chain = function(obj) {
      var instance = _(obj);
      instance._chain = true;
      return instance;
    };
  • 相关阅读:
    nyoj131 小数相加 循环小时转换分数
    STL 之priority_queue
    XML序列化
    Change the hightlight item color
    TreeView ListView ItemSource
    .NET 下的序列化与反序列化
    WPF: WebBrowser TO Bitmap
    隐藏/显示 Office 标题栏 工具栏 winform webBrowser
    WPF全屏幕窗口
    .Net 注册表操作
  • 原文地址:https://www.cnblogs.com/walkingp/p/10750965.html
Copyright © 2020-2023  润新知