日期:2014-05-16 浏览次数:20374 次
Extjs的事件也是经过良好封装的,对于事件的处理都由Ext.uitl.Observable类提供接口。这里接口的意思是Observable实际上起了一个抽象类的作用,Extjs中有大量的组件都是继承自这个类的。这个类提供了一些基本的方法比如addEvents,addlistener,fireEvent等等。
本文暂时不介绍如何使用extjs的组件响应事件,而是介绍Extjs的事件的一些实现原理。整个Extjs框架都是以一种面向对象的方式开发的,所以理解Javascript中的继承也很重要。
Extjs实现继承的函数是一个很核心的函数Ext.extend,extend方法有两个重构版本,第一个接受两个参数,第一个是extend( Function superclass
, Object overrides
) ,第二个是extend( Function subclass
, Function superclass
,Object overrides
) : Function,第二个版本是在subclass的基础上。superclass就是超类的构造函数,overrides是一个对象,里边的属性就是要覆盖父类的属性。继承了父类的子类具有父类的prototype中的所有方法。并且子类可以覆盖父类的方法(override),更进一步,子类的每个对象也可以覆盖父类的方法。其实我觉得这个函数没什么作用,修改prototype的效果是等效的,当然,extjs的目的肯定是要把prototype这个神奇的东西完全屏蔽起来,使程序员能够像处理其他语言一样来处理Javascript。当然,即使如此,它的继承和一般的继承还是有些不同的,下面先看个例子,准备好一个Person类
Person = function(name) { this.name = name; this.fn = function() { alert('I am a person') }; } Person.prototype.print=function(){ alert('I am a person');} Person.prototype.showAge = function() { alert('I am older than 0'); } Person.prototype.showName = function() { alert('Show Name:'+this.name) }; var per = new Person('Tom'); per.showName();
子类:
Student = function(id) { this.id = id; } Student.prototype.showID = function() { alert(this.id); } //子类的方法 继承: Ext.extend(Student, Person); stu.showName(); !!没有结果!stu没有name的定义
stu.fn(); !!没有结果
stu.showID(); !!!还是没有结果
到此我们已经发现了一些不同:在父类的构造函数中的内容是不会继承的,父类的构造函数不会被调用,子类(prototype中)已有的方法也会丢失!继续看下去,将Ext.extend下面的代码替换成:
var stu = new Student('01'); Student.override({ print: function() { alert('I am a student'); } }); stu.override({ print: function() { alert('I am a bad student,but I won\'t affect others'); } }); stu.print(); stu.showAge(); var stu2 = new Student(); stu2.print();
这里的函数都能够按预期输出,showAge是执行的父类的方法,stu.print是执行的stu.override中指定的方法,而stu2执行的是Student.override中指定的方法。到这里,我们已经大概能猜出extend是如何实现的了。下面看它真正的源代码,这个方法位于Ext.js中,代码和注释如下:
extend : function(){ // inline overrides var io = function(o){ //注意这个方法的this,仅看这里并不知道这个this是什么,下面这个io会被赋值给sbp.override,也就是子类的prototype for(var m in o){ //从而每个子类的对象的override都会指向这个方法,如果子类对象调用了override,那么这个this就是子类的对象了。也就是 this[m] = o[m]; //上面的例子中stu.override表现出来的效果,仅对当前对象有效。从这里可以看出,override不仅仅是传统意