现在的位置: 首页 > 综合 > 正文

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

2012年03月19日 ⁄ 综合 ⁄ 共 2034字 ⁄ 字号 评论关闭

概述

前面讲过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控件。

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

抱歉!评论已关闭.