• 解读rightjs的继承机制2


    Class.Methods是一个方法集合,把经常用到的方法移出函数体是一个陪明的做法,这样不就用每次进入函数体就反复创建它们。

    从另一个角度看,Class.Methods是自动执行函数,YUI的人好像把它归类为模块模式,EXT这样的用法很多,把许多变量与只对当前模块有用的方法捆绑在一个闭包中,减少命名冲突。

     
          Class.Methods = (function() {
            //一系列方法名,可以看到include涉及最多东西
            var commons = $w('selfExtended self_extended selfIncluded self_included'),
            extend  = commons.concat($w('prototype parent extend include')),
            include = commons.concat(['constructor']);
            //用来清理模块中不需要的方法
            //相当于module.without(extend)或module.without(include)
            function clean_module(module, what) {
              return Object.without.apply(Object, [module].concat(what == 'e' ? extend : include));
            };
    
            return {
               //方法集合
            }
          })();
    

    上面有些写法很不妥,如 commons.concat(['constructor']),直接commons.concat('constructor')就可以了。不过最大的问题是Object.without方法:

     
      without: function() {
        var filter = $A(arguments), object = filter.shift(), copy = {}, key;
        for (key in object)
          if (!filter.includes(key))
            copy[key] = object[key];
    
        return copy;
      },
    

    在IE下,for...in循环是有许多属性不能遍历出来的,如valueOf、toString……

    看inherit方法,它暗中运用了桥梁模式,使用子类与父类的原型不再连在一起。而且通过new原型的方法,比属性拷贝快很多。

     
    inherit: function(parent) {
        // 获取父类的原型属性
        if (parent && parent.prototype) {
          var s_klass = function() {};
          s_klass.prototype = parent.prototype;
          this.prototype = new s_klass;
          this.parent = parent;
        }
        // 收集父类
        this.ancestors = [];
        while (parent) {
          this.ancestors.push(parent);
          parent = parent.parent;
        }
       //修正原型上的constructor属性
        return this.prototype.constructor = this;
      },
    

    下面方法为新类扩展静态成员,这是ruby的写法,在jQuery,无论是为jQuery命名空间添加成员还是为jQuery对象添加实例方法都是用extend,比较无言。

     
    extend: function() {
        $A(arguments).filter(isHash).each(function(module) {
         //用于实现ruby的那种自扩展机制
          var callback = module.selfExtended || module.self_extended;
    
          $ext(this, clean_module(module, 'e'));
    
          if (callback) callback.call(module, this);
        }, this);
    
        return this;
      },
    

    include则为新类扩展原型成员,也是ruby的命名方式。在mootools中,则为implement。觉得mootools与rights从ruby中借鉴了不少东西啊。ruby果然是最强的OO脚本语言。

     
          include: function() {
            //取得所有超类的原型
            var ancestors = this.ancestors.map('prototype'), ancestor;
            //移参数转换为纯对象数组并迭代它们
            $A(arguments).filter(isHash).each(function(module) {
              //用于ruby式的自包含
              var callback = module.selfIncluded || module.self_included;
              //清理一些危险的方法,防止覆盖
              module = clean_module(module, 'i');
    
              for (var key in module) {
                //取得最近的与它有重名方法的祖先
                ancestor = ancestors.first(function(proto) { return isFunction(proto[key]); });
                //如果有,则重写此方法,返回一个currying
                this.prototype[key] = !ancestor ? module[key] :
                  (function(name, method, super_method) {
                  return function() {
                    //用于方法链
                    this.$super = super_method;
                    return method.apply(this, arguments);
                  };
                })(key, module[key], ancestor[key]);
              }
              //执行自包含
              if (callback) callback.call(module, this);
            }, this);
    
            return this;
          }
    

    此外,Class还有一个方法,不过作为辅助方法,不加入类工厂中的。

     
    //从当前类或其祖先中,寻找特定的属性
    Class.findSet = function(object, property) {
      var upcased = property.toUpperCase(), capcased = property.capitalize(),
        candidates = [object, object.constructor].concat(object.constructor.ancestors),
        holder = candidates.first(function(o) { return o && (o[upcased] || o[capcased]) });
    
      return holder ? holder[upcased] || holder[capcased] : null;
    };
    
  • 相关阅读:
    VS2015中SharedProject与可移植类库(PCL)项目
    Windows.Web.Http.HttpClient.GetStringAsync 总是返回相同的结果
    博客园新闻WP8.1客户端
    Webpack 2 视频教程 001
    快速零配置迁移 API 适配 iOS 对 IPv6 以及 HTTPS 的要求
    免费的 Vue.js 入门与进阶视频教程
    Webpack 3 中的新特性
    使用可视化图表对 Webpack 2 的编译与打包进行统计分析
    React.js 开发参见问题 Q&A
    官方 React 快速上手脚手架 create-react-app
  • 原文地址:https://www.cnblogs.com/rubylouvre/p/1701524.html
Copyright © 2020-2023  润新知