• JS 继承:extend、mixin 和 plugin(三)



    概述

    前面讲过JS原型链的继承和扩展方式mixin的方式,2种方式都是直接作用到类本身上,虽然实现机制有差异,但是在运行时的上下文(context)也就是 this 引用是相同的,这样的继承方式无疑使最方便的,但是这里面有几个问题要解决:

    1.         耦合性过高,因为使用的都是this上下文,所以所有的变量和私有函数(js本身不支持,但是可以约定)都有访问权,这样对组织和维护代码带来问题,父类内部逻辑的改变直接影响到本身。

    2.         函数会相互覆盖,因为这2中方式最终都是将函数附加到类的原型链上,会出现意外的覆盖问题

    3.         修改添加新功能成本高,进行功能扩展时需要对父类以及mixin有深入的了解,类的编写者问题不大,但是其他人员来扩展时就非常麻烦。

    plugin的机制

    一个JS(控件)于它的Plugin的关系仅仅是依赖关系,plugin不了解控件的内部实现,只了解类的公共接口和公共属性,只是通过这些公共属性和方法去操纵控件。这样只要控件的接口保持不变,它的plugin始终是可用的,降低了耦合性。我们来看一下plugin的简单实现:

      //类Grid 是一个控件
      //这里仅仅是示例
      function Grid(config){
        this.plugins = config.plugins;
        //初始化插件
        this.plugins = initPlugins(plugins);
        //To Do
      }
     
      Grid.prototype = {
        //初始化
        initPlugins : function(plugins){
          var result = [];
          $.each(plugins,function(index,plugin)){
            //可以判断plugin是否实例化...
            var p = new plugin();
            p.initializer(this);
            //To Do something
            result.push(p);
          }
          return result;
        },
        //绑定事件时
        bindUI : function(){
          //and so on
          $.each(this.plugins,function(index,plugin)){
            plugin.bindUI(this);
          }
        }
      };
       
      //类B是A的插件
      function B(){
       
      }
     
      B.prototype = {
        //初始化方法接收A的示例
        initializer : function(grid){
          this.grid = grid;
          ....
        },
        bindUI : function(){
          var grid = this.grid;
          //To do
          grid.on('cellclick',function(){});
        }
      }
     
      //类B是A的插件
      function C(){
       
      }
     
      var a = new A({
        plugins:[B,C]
      });

      

    这里只是一个简单的实现,前面我讲过控件的生命周期,在每个周期控件都会调用自己的plugins进行相应的操作,例如:创建DOM、绑定事件以及销毁。

    pluginmixin

    pluginmixin 都是对控件的一种扩展方式,在最前面我们也讲到了一些差别,概括起来:

    1. 相同的地方:

    1)         都是对控件进行扩展

    2)         整个生命周期都受控件管理

    2. 不同的地方:

    1)         上下文不同,也就是 this 引用不同

    2)         对控件的操作权限不同,mixin能控制控件所有的变量和函数,plugin只能处理公用方法和变量

    3)         mixin是抽象层次的,行为上像一个抽象类,可以由多个控件来使用,而且多个控件之间没有继承上的关系。

    4)         plugin是实现层次的,是一个适配器,只能作用于一个控件或者其子类。

    拿具体的实例来说:

    例如,拖拽功能,我们可以把它做成控件的一个扩展 mixin,只要指定了要拖动的位置,就可以拖动这个控件,不同的控件都可以使用。


     

    例如,一个级联的Grid,我给Grid写的plugin 只能作用在Grid及其子类上。


    总结

    JS类的继承方式我已经讲完了,这3种方式都非常有用,各有其适应环境,一套控件如果都有支持这几种机制,那么它的扩展性就非常的好,后面我会拿具体的实例来说明。

    我想把自己基于jquery的一套UI库作为示例,来讲解如何写一套易于扩展、易用的JS控件。


    不知道各位最感兴趣的是哪个控件。

  • 相关阅读:
    *Path Sum II
    *Path Sum
    Same Tree
    Symmetric Tree
    hprof网络连接
    gc
    java thread park
    sudo !!
    ecb gud
    jpda
  • 原文地址:https://www.cnblogs.com/zaohe/p/plugin.html
Copyright © 2020-2023  润新知