Mootools类定义增强因子
来源:广州中睿信息技术有限公司官网
发布时间:2012/10/21 23:25:16 编辑:admin 阅读 310
最近研习《ProJavascriptwithMootools》,跟jQuery比起来,Mootools的资料算是少之又少的(Mootools在用户推广和社区建设方面有必要向jQuery学习下)。这本

最近研习《Pro Javascript with Mootools》,跟jQuery比起来,Mootools的资料算是少之又少的(Mootools在用户推广和社区建设方面有必要向jQuery学习下)。这本书比较全面的对Mootools-core中各个关键模块做了说明和分析,每章都由原生javascript逐渐引入,总之是本不错的书,虽然现在jQuery在业界大红大紫, 但个人也希望mootools能得到不错的发展。

回到正题,Mootools跟jQuery一个比较显著的差异就是在代码组织方式上,Mootools引入了OOP思想,实现了功能强大的Class类。

Mootools默认内置了两个Class的增强因子,一个是Extends,另外一个是Implements.

有一定Mootools使用经验的园友应该很熟悉这两个扩展,内部都用于实现javascript的prototype链继承(但是不仅仅如此)。

不同的是Extends模拟OOP中子类继承父类的操作,Implements的话可以理解成继承方法(和Java或者C#中实现接口有些不同,接口只是函数声明,没有定义)。

下面个例子:

var Human = new Class({      // 初始化方法      initialize: function(name, gender) {          this.name = name;          this.gender = gender;      },          toString: function() {          return 'name:' + this.name + ',' + 'gender:' + this.gender;      }    });    var Behavior = new Class({        eat: function() {          console.log(this.name + ' wanna grab something to eat');      },            sleep: function() {          console.log(this.name + ' wanna sleep');      },            haveFun: function() {          console.log(this.name + ' wanna have some fun');      }    });    var Developer = new Class({            Extends: Human,            Implements: Behavior,            initialize: function(name, gender, lang) {          this.parent(name, gender); //调用父类中对应的方法          this.lang = 'javascript';      },            toString: function() {          return this.parent() + ',language:' + this.lang;      }  });    var Andrew = new Developer('Andrew', 'male', 'javascript');   console.log(Andrew.toString()); // name:Andrew,gender:male,language:javascript  Andrew.eat();                   // Andrew wanna grab something to eat  Andrew.sleep();                 // Andrew wanna sleep  Andrew.haveFun();               // Andrew wanna have some fun  

从这个例子出应该不难看出Extends和Implements所起到的作用,如果你像我一样对其中的实现细节很感兴趣,可以研究下Mootools中的Class模块,一开始去看源码确实有点困难,硬着头皮多看几遍就慢慢有点思路了。这里有篇园友的随笔,他对Class模块做了一些注释,足够了解其运行机制。点击浏览此文,感谢苦苦的苦瓜

除了基本的Extends和Implements,我们还可以实现自定义的增强因子,从源码中我们可以看出,Class模块的增强因子通过Class.Mutators进行扩展。下面给出源码,我们可以有个参照。

Class.Mutators = {     Extends: function(parent){    this.parent = parent;    this.prototype = getInstance(parent);   },     Implements: function(items){    Array.from(items).each(function(item){     var instance = new item;     for (var key in instance) implement.call(this, key, instance[key], true);    }, this);   }  };  

一下子看不大明白很正常,如果要分析源码,篇幅会很长,这里其实只要搞清一些注意点就行. 结合之前的Developer例子看,Class.Mutators.Extends执行时,其中this指的就是构造类Developer(记得吗,我们通过new Developer来产生一个实例),其中parent就是继承的Human构造类,getInstance(parent)返回Human的实例,这里很明显就是基于prototype的继承实现(但不仅如此,就这块代码而言是这样)。再简单的看下Class.Mutators.Implements,运行时通过其中的implement方法给Developer的prototype扩展方法或属性。

现在来个自定义的例子,我们自己动手干, 来实现一个自动实现属性getter,setter方法:

// mootools Mutator GetterSetter    Class.Mutators.GetterSetter = function(props) {     var klass = this;     Array.from(props).each(function(prop) {      var capProp = prop.capitalize();             klass.implement('set' + capProp, function(value) {       this[prop] = value;       return this;      });            klass.implement('get' + capProp, function(value) {       return this[prop];      });     });    };  

如果我们把GetterSetter用于Developer构造类的定义,那么Class.Mutators.GetterSetter执行时,this指的就是Developer。我们看一下each里面的回调,通过闭包klass维持着对Developer的引用,通过implement方法在其prototype上扩展属性的setter,getter方法。这样Developer的实例就自动拥有了类似Java类中的setter,getter。通过扩展Class.Mutators,我们优雅的实现了这个功能。来验证一下:

 var Developer = new Class({          Extends: Human,          Implements: Behavior,          GetterSetter: ['name', 'gender', 'lang'],          initialize: function(name, gender, lang) {      this.parent(name, gender);      this.lang = 'javascript';     },          toString: function() {      return this.parent() + ',language:' + this.lang;     }    });      var Andrew = new Developer('Andrew', 'male', 'javascript');    console.log(Andrew.getName());    // Andrew    console.log(Andrew.getGender());  // male    console.log(Andrew.getLang());    // javascript  

 个人觉得很强大,再来一个实现模拟静态属性(static)的例子:

  Class.Mutators.Static = function(props) {     this.extend(props);    };  

看起来再简单不过了,不是么?我们再来验证一下:

 var Developer = new Class({     Static: {      count: 0,            addCount: function() {       Developer.count++;      }     },          Extends: Human,          Implements: Behavior,          initialize: function(name, gender, lang) {      this.parent(name, gender);      this.lang = 'javascript';            Developer.addCount();     },          toString: function() {      return this.parent() + ',language:' + this.lang;     }    });      var Andrew = new Developer('Andrew', 'male', 'javascript');    var Rocky = new Developer('Rocky', 'male', 'php');    console.log(Developer.count); // 2  

 我们通过count给实例化的对象计数,或许你会觉得count和addCount就这么暴露给外部是个问题,我们可以用匿名函数来模拟实现private:

var Developer = (function() {          // private variable or function     var count = 0,        addCount = function() {       count++;      };          return new Class({      Static: {        getCount: function() {        return count;       }      },            Extends: Human,            Implements: Behavior,            initialize: function(name, gender, lang) {       this.parent(name, gender);       this.lang = 'javascript';              addCount();      },            toString: function() {       return this.parent() + ',language:' + this.lang;      }     });    })();      var Andrew = new Developer('Andrew', 'male', 'javascript');    var Rocky = new Developer('Rocky', 'male', 'php');    console.log(Developer.count);        // undefined                  console.log(Developer.addCount());   // undefined    console.log(Developer.getCount());   // 2  

注意到,我们利用匿名函数和闭包特性模拟实现了count和addCount的private,对比之前外部可以通过Developer.count或者Developer.addCount直接改变计数显得安全的多了。

最后就jQuery和Mootools,我想再稍微吐糟一下。

jQuery为何如此流行:它起点低,入门简单,不怎么懂javascript的程序员或者设计师,都可以简单上手,而且它的文档做的很不错,用户推广做的好,社区活跃,不可否认jQuery形势一片大好,在结合BackBone等MVC framework的辅助,真是不错。

Mootools虽然几乎和jQuery同时出现,但是其社区规模和受欢迎程度确实没有jQuery高,从github上watch和fork人数就可见一斑。一方面Mootools的上手确实不太适合javascript初学者,另一方面对于很多程序员来讲,貌似并不需要Mootools的对OOP的实现,而jQuery对于DOM操作和特效的实现更为简单...所以,Mootools现在的情况有点小尴尬,不过它依然是一个很好的framework。希望也能很好的发展。

联系我们CONTACT 扫一扫
愿景:成为最专业的软件研发服务领航者
中睿信息技术有限公司 广州•深圳 Tel:020-38931912 务实 Pragmatic
广州:广州市天河区翰景路1号金星大厦18层中睿信息 Fax:020-38931912 专业 Professional
深圳:深圳市福田区车公庙有色金属大厦509~510 Tel:0755-25855012 诚信 Integrity
所有权声明:PMI, PMP, Project Management Professional, PMI-ACP, PMI-PBA和PMBOK是项目管理协会(Project Management Institute, Inc.)的注册标志。
版权所有:广州中睿信息技术有限公司 粤ICP备13082838号-2