本文暫時(shí)不介紹如何使用extjs的組件響應(yīng)事件 " /> 国产色精品久久人妻99蜜桃麻豆,三级黄色高清视频,亚洲国产精品一区二区久久第

天天躁日日躁狠狠躁AV麻豆-天天躁人人躁人人躁狂躁-天天澡夜夜澡人人澡-天天影视香色欲综合网-国产成人女人在线视频观看-国产成人女人视频在线观看

Extjs學(xué)習(xí)筆記之八 繼承和事件基礎(chǔ)

這里接口的意思是Observable實(shí)際上起了一個(gè)抽象類的作用,Extjs中有大量的組件都是繼承自這個(gè)類的。這個(gè)類提供了一些基本的方法比如addEvents,addlistener,fireEvent等等。

本文暫時(shí)不介紹如何使用extjs的組件響應(yīng)事件,而是介紹Extjs的事件的一些實(shí)現(xiàn)原理。整個(gè)Extjs框架都是以一種面向?qū)ο蟮姆绞介_(kāi)發(fā)的,所以理解Javascript中的繼承也很重要。我前面的一篇文章 補(bǔ)點(diǎn)基礎(chǔ):Javascript中的類和閉包 也是為這篇做準(zhǔn)備。另外,博客園內(nèi)還有一個(gè)寫的很好的系列 JavaScript繼承詳解. 他主要是根據(jù)Douglas Crockford的兩篇文章寫的。 其實(shí)實(shí)現(xiàn)繼承的原理都差不多,大家可以參考閱讀。

Extjs實(shí)現(xiàn)繼承的函數(shù)是一個(gè)很核心的函數(shù)Ext.extend,extend方法有兩個(gè)重構(gòu)版本,第一個(gè)接受兩個(gè)參數(shù),第一個(gè)是extend( Function superclass, Object overrides ) ,第二個(gè)是extend( Function subclass, Function superclass,Object overrides ) : Function,第二個(gè)版本是在subclass的基礎(chǔ)上。superclass就是超類的構(gòu)造函數(shù),overrides是一個(gè)對(duì)象,里邊的屬性就是要覆蓋父類的屬性。繼承了父類的子類具有父類的prototype中的所有方法。并且子類可以覆蓋父類的方法(override),更進(jìn)一步,子類的每個(gè)對(duì)象也可以覆蓋父類的方法。其實(shí)我覺(jué)得這個(gè)函數(shù)沒(méi)什么作用,修改prototype的效果是等效的,當(dāng)然,extjs的目的肯定是要把prototype這個(gè)神奇的東西完全屏蔽起來(lái),使程序員能夠像處理其他語(yǔ)言一樣來(lái)處理Javascript。當(dāng)然,即使如此,它的繼承和一般的繼承還是有些不同的,下面先看個(gè)例子,準(zhǔn)備好一個(gè)Person類
復(fù)制代碼 代碼如下:
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(); !!沒(méi)有結(jié)果!stu沒(méi)有name的定義stu.fn(); !!沒(méi)有結(jié)果 stu.showID(); !!!還是沒(méi)有結(jié)果到此我們已經(jīng)發(fā)現(xiàn)了一些不同:在父類的構(gòu)造函數(shù)中的內(nèi)容是不會(huì)繼承的,父類的構(gòu)造函數(shù)不會(huì)被調(diào)用,子類(prototype中)已有的方法也會(huì)丟失!繼續(xù)看下去,將Ext.extend下面的代碼替換成:
復(fù)制代碼 代碼如下:
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();

這里的函數(shù)都能夠按預(yù)期輸出,showAge是執(zhí)行的父類的方法,stu.print是執(zhí)行的stu.override中指定的方法,而stu2執(zhí)行的是Student.override中指定的方法。到這里,我們已經(jīng)大概能猜出extend是如何實(shí)現(xiàn)的了。下面看它真正的源代碼,這個(gè)方法位于Ext.js中,代碼和注釋如下:extend : function(){
復(fù)制代碼 代碼如下:
// inline overrides
var io = function(o){ //注意這個(gè)方法的this,僅看這里并不知道這個(gè)this是什么,下面這個(gè)io會(huì)被賦值給sbp.override,也就是子類的prototype
for(var m in o){ //從而每個(gè)子類的對(duì)象的override都會(huì)指向這個(gè)方法,如果子類對(duì)象調(diào)用了override,那么這個(gè)this就是子類的對(duì)象了。也就是
this[m] = o[m]; //上面的例子中stu.override表現(xiàn)出來(lái)的效果,僅對(duì)當(dāng)前對(duì)象有效。從這里可以看出,override不僅僅是傳統(tǒng)意義上的覆蓋,完全也可以
} //用來(lái)添加新方法。
};
var oc = Object.prototype.constructor;

return function(sb, sp, overrides){
if(Ext.isObject(sp)){ //是在檢測(cè)當(dāng)前使用的是哪個(gè)版本的重構(gòu)函數(shù)。如果sp實(shí)際上是overrides,就做些替換工作,讓變量的實(shí)際意義和名稱相符合。
overrides = sp;
sp = sb;
sb = overrides.constructor != oc ? overrides.constructor : function(){sp.apply(this, arguments);}; //這個(gè)沒(méi)看懂……
}
var F = function(){},
sbp,
spp = sp.prototype;

F.prototype = spp; //F是父類的一個(gè)“干凈”拷貝,所謂干凈,是指它不會(huì)把父類中在構(gòu)造函數(shù)內(nèi)部定義的屬性帶過(guò)來(lái)。 //例如 Person=function() // {this.privateFn=new function{ some code goes here}} //那么這個(gè)privateFn對(duì)子類是不可見(jiàn)的,所以在構(gòu)造函數(shù)中利用this定義的屬性都相當(dāng)于是類的私有變量。
sbp = sb.prototype = new F(); //將子類的prototype設(shè)置為父類的prototype,繼承的核心步驟。 sbp.constructor=sb; //設(shè)置正確的構(gòu)造函數(shù)指向,見(jiàn) JavaScript繼承詳解
sb.superclass=spp; //設(shè)置父類
if(spp.constructor == oc){ //沒(méi)看懂……,這個(gè)是干嘛用的?望高人指點(diǎn)
spp.constructor=sp;
}
sb.override = function(o){ //子類的重寫方法,這個(gè)重寫方法是函數(shù)的重寫方法。它修改的是prototype。
Ext.override(sb, o); //見(jiàn)最后。
};
sbp.superclass = sbp.supr = (function(){ //設(shè)置原型的父類
return spp;
});
sbp.override = io; //給子類的prototype提供override方法,這樣單個(gè)實(shí)體也可以覆蓋,它修改的是實(shí)體對(duì)象。注意和上面的sb的override區(qū)分。
Ext.override(sb, overrides); //重寫
sb.extend = function(o){return Ext.extend(sb, o);}; //給子類提供extend方法,以實(shí)現(xiàn)多重繼承
return sb; //返回子類。
};
}();

下面是Ext.override的代碼,比較明了的,和那個(gè)inline override相比,它就是修改的prototype:override :
復(fù)制代碼 代碼如下:
function(origclass, overrides){
if(overrides){
var p = origclass.prototype;
Ext.apply(p, overrides);
if(Ext.isIE && overrides.hasOwnProperty('toString')){ // 這個(gè)是什么?IE的特殊點(diǎn)?
p.toString = overrides.toString;
}
}
}

現(xiàn)在就可以開(kāi)始正式介紹Extjs的事件模型了。和其他語(yǔ)言事件類似,首先要為一個(gè)類定義事件,其他語(yǔ)言(例如C#)的事件一般有一個(gè)專門的event類型,event類型實(shí)際上可以看作是委托的數(shù)組,當(dāng)然委托實(shí)際上是函數(shù),添加時(shí)間監(jiān)聽(tīng)器(listener),就是想委托數(shù)組中添加委托(函數(shù)),所謂觸發(fā)事件就是把數(shù)組中的函數(shù)統(tǒng)統(tǒng)執(zhí)行一遍。Javascript也是類似的,只是Javascript的函數(shù)比那些語(yǔ)言強(qiáng)大靈活的多,因此也不需要什么event類型了。Javascript的事件看起來(lái)就像一個(gè)字符串(它內(nèi)部應(yīng)該也是保留了一個(gè)數(shù)組的),可以通過(guò)Observale.addEvents方法添加事件,通過(guò)Observale.fireEvent觸發(fā)事件,通過(guò)Observale.addListner增加事件監(jiān)聽(tīng)器。下面舉一個(gè)沒(méi)什么意義卻能說(shuō)明問(wèn)題的例子。
復(fù)制代碼 代碼如下:
Odder = function(min, max) {
this.min = min;
this.max = max;
this.addEvents('onFindOdd');
}
Ext.extend(Odder, Ext.util.Observable, { run:
function() {
for (var i = this.min; i < this.max; i++) {
if (i % 2 != 0) {
this.fireEvent('onFindOdd',i);
}
}
}
});
var p = new Odder(4, 8);
p.addListener('onFindOdd',function(n){alert(n);});
p.run();

Odder是這么一個(gè)類,它通過(guò)一個(gè)構(gòu)造函數(shù)傳入一個(gè)范圍,然后尋找這個(gè)范圍內(nèi)的所有奇數(shù),每找到一個(gè)就觸發(fā)一個(gè)事件。我給它加一個(gè)事件處理程序,把它找到的奇數(shù)alert出來(lái)。 要注意,這里的事件處理程序的參數(shù)只能靠程序員自己保持一致,它不像委托那樣強(qiáng)類型。

注意,我沒(méi)有采用官網(wǎng)上的例子:
復(fù)制代碼 代碼如下:
Employee = Ext.extend(Ext.util.Observable, {
constructor: function(config){
this.name = config.name;
this.addEvents({
"fired" : true,
"quit" : true
});

// Copy configured listeners into *this* object so that the base class's
// constructor will add them.
this.listeners = config.listeners;

// Call our superclass constructor to complete construction process.
Employee.superclass.constructor.call(config)
}
});This could then be used like this:
var newEmployee = new Employee({
name: employeeName,
listeners: {
quit: function() {
// By default, "this" will be the object that fired the event.
alert(this.name + " has quit!");
}
}
});

我覺(jué)得官網(wǎng)上的例子內(nèi)部還有文章,它的重載項(xiàng)中包含了constructor屬性,給人的感覺(jué)是是重載了父類的構(gòu)造函數(shù),然后子類就會(huì)調(diào)用這個(gè)構(gòu)造函數(shù)來(lái)創(chuàng)建,其實(shí)不是的,它改變了Javascript本身的行為,這個(gè)就和我上面標(biāo)注的沒(méi)有看懂的那幾句代碼有關(guān)系。下回再討論。

JavaScript技術(shù)Extjs學(xué)習(xí)筆記之八 繼承和事件基礎(chǔ),轉(zhuǎn)載需保留來(lái)源!

鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標(biāo)記有誤,請(qǐng)第一時(shí)間聯(lián)系我們修改或刪除,多謝。

主站蜘蛛池模板: 经典三级四虎在线观看 | 大地影院免费观看视频 | 7723手机游戏破解版下载 | 久久香蕉电影 | 丰满的大白屁股ass 丰满大屁俄罗斯肥女 | 91精品免费久久久久久久久 | 国产成人精品综合久久久 | 午夜dj影院视频观看 | 18美女腿打开无遮软件 | 18和谐综合色区 | 青柠视频在线观看高清HD | 久久机热视频免费 | 国产精品久久久久久久久LI无码 | 日本三级黄色大片 | 97影院理论午夜伦不卡偷 | 免费看a视频| 手机在线播放成人亚洲影院电影 | 大乳牛奶女在线观看 | 亚洲一区乱码电影在线 | 天天摸夜添狠狠添高 | 久久机热免费视频 | 日韩AV无码一区二区三区不卡毛片 | 久久久99精品成人片中文 | 国产精品成人免费 | 成人欧美一区二区三区白人 | 手机看片成人 | 久久国产免费观看精品1 | 男污女XO猛烈的动态图 | 久久99精品AV99果冻 | 女人夜夜春 | 港台三级大全 | 最新精品学生国产自在现拍 | 国产精品免费久久久久影院 | 国产精品大陆在线视频 | 日本XXXXZZX片免费观看 | 成人无码精品一区二区在线观看 | 成人无码国产AV免费看 | 2021国产在线视频 | 3D漫画H精品啪啪无码 | 99久久做夜夜爱天天做精品 | 大陆午夜伦理 |