欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Javascript Object.extend

 更新時(shí)間:2010年05月18日 01:11:01   作者:  
上回說到了類的定義,prototype通過一個(gè)全局對(duì)象Class從形式上將函數(shù)和類區(qū)別開來。
既然是類,那么就有抽象類,具體類,類的繼承,同時(shí),類的成員可以有實(shí)例成員和靜態(tài)成員。下面來看一下prototype是怎么做到這些的。
先看prototype中的以下的代碼:
復(fù)制代碼 代碼如下:

var Abstract = new Object();
Object.extend = function(destination, source) {
for (property in source) {
destination[property] = source[property];
}
return destination;
}
Object.prototype.extend = function(object) {
return Object.extend.apply(this, [this, object]);
}

第一個(gè)聲明了一個(gè)對(duì)象Abstract,Object其實(shí)是一個(gè)函數(shù),他沒有任何成員,所以是一個(gè)空類,所以Abstract也就沒有任何成員。這個(gè)暫時(shí)不說,后面可以看到這是抽象類的基礎(chǔ)。先解釋以下這個(gè)語法:
function.member=function(){}
在這種情況下,function一般都是已經(jīng)定義過的,這條語句的作用是給function增加一個(gè)靜態(tài)成員member,member的內(nèi)容是等號(hào)后面的。如上面第二段代碼Object.extend=……,就是給Object這個(gè)類增加了一個(gè)靜態(tài)方法extend。ok,我們知道了怎樣給一個(gè)類定義靜態(tài)成員,那么你一定很想知道實(shí)例成員怎么定義,很簡(jiǎn)單,在類名和成員名之間加上prototype:
function.prototype.member=function(){}
prototype不僅可以這么使用,還可以:
復(fù)制代碼 代碼如下:

function.prototype={
member1:function(){……},
member2:"abc",
member3:function(){……}
}

這樣就是實(shí)現(xiàn)了實(shí)例成員的定義。但prototype代表什么意思呢?在第一篇我說過,直接用{}括起來,表示一個(gè)對(duì)象,如Prototype,Class都是這樣定義的全局對(duì)象。而看下面一種用法,prototype后面就是一個(gè){}的結(jié)構(gòu),難道它也是對(duì)象?是的,沒錯(cuò),prototype其實(shí)也是一個(gè)對(duì)象!在javascript里,一個(gè)對(duì)象我們可以任意增加它的成員,用如下的語法:
object.member=function(){……};
只要經(jīng)過這樣的定義,一個(gè)對(duì)象就可以立刻具有member這個(gè)方法!javascript就是這么神奇!
好,我們現(xiàn)在知道了prototype是一個(gè)對(duì)象,而function是一個(gè)函數(shù)或者類,那么我們可以認(rèn)為prototype是任何一個(gè)類(函數(shù))都內(nèi)部保留的一個(gè)靜態(tài)成員。它的功能就是存儲(chǔ)這個(gè)類的所有成員指針,但這些成員都只是原型,沒有經(jīng)過初始化,這也符合prototype的原義。你可以隨時(shí)通過prototype這個(gè)對(duì)象來擴(kuò)充成員。在new一個(gè)類時(shí),prototype的成員就經(jīng)過初始化,然后賦給了實(shí)例化的對(duì)象。
上面第三段代碼Object.prototype.extend=……,就是給Object增加了一個(gè)實(shí)例方法extend,實(shí)例方法中就可以引用this指針,指向由這個(gè)類實(shí)例化的對(duì)象本身。當(dāng)然,這個(gè)對(duì)象就具有成員extend。
繼續(xù)之前,先了解一下兩個(gè)語句:
for(var p in object){}
method.apply(object,arguments);
第一句:列舉出一個(gè)變量的所有成員,如果是函數(shù),那么是所有靜態(tài)成員;如果是對(duì)象,那就是所有實(shí)例成員,p的類型是一個(gè)字符串。表示成員的名稱。引用一個(gè)成員不僅可以用variabel.member,還可以用variabel["member"]。反過來,賦值也是如此。這就給枚舉一個(gè)變量的成員帶來了很大方便。
第二條語句:將method這個(gè)方法應(yīng)用到object去執(zhí)行,參數(shù)是arguments這個(gè)數(shù)組。注意:method并不是object的成員。但是,我們可以認(rèn)為這條語句執(zhí)行的意思就是:object.method(arguments)。這是一個(gè)很重要的方法,后面會(huì)經(jīng)常用到,你也會(huì)逐漸熟悉它的。
下面繼續(xù)extend,它是一個(gè)非常重要的方法,可以看到它既是類Object的靜態(tài)成員,也是其實(shí)例成員,那它有什么作用呢?讓我們來看:它接收兩個(gè)參數(shù),destination和source,如果destination和source都是類,那么它的功能是把類source的所有靜態(tài)成員都復(fù)制給類destination,如果destination和source都是對(duì)象,那么是把所有實(shí)例成員都復(fù)制過來。這時(shí)destination中如果已經(jīng)有同名成員,那么這個(gè)成員將被覆蓋。也就是說讓destination具有了source的所有成員,并且函數(shù)返回這個(gè)destination。下面看extend作為Object的實(shí)例成員:
Object.prototype.extend = function(object) {
return Object.extend.apply(this, [this, object]);
}
開始有點(diǎn)暈了,不過不要急,還是可以看懂的,apply語法剛剛已經(jīng)講過了,它的調(diào)用者是一個(gè)方法,而Object.extend是一個(gè)靜態(tài)方法,它被應(yīng)用到this上面,也就是Object的實(shí)例,假設(shè)為obj,后面方括號(hào)是一個(gè)數(shù)組,包括兩個(gè)成員,this和object。這個(gè)數(shù)組實(shí)際上就是Object靜態(tài)成員extend的arguments參數(shù)。那么這條語句就相當(dāng)于執(zhí)行
obj.extend(this,object);
this不解釋了,表示本身。object是什么?參數(shù),恩,是實(shí)例方法extend傳來的參數(shù),不要混淆。extend呢?obj并沒有定義extend實(shí)例成員,但通過apply,它可以把Object的靜態(tài)成員extend拿來使用,再看一下extend的函數(shù)體:
Object.extend = function(destination, source) {
for (property in source) {
destination[property] = source[property];
}
return destination;
}
因?yàn)閛bj是對(duì)象,object也是對(duì)象,即destination和source都是對(duì)象,于是函數(shù)的作用就是使obj具有object的所有成員。并且會(huì)返回obj。聽起來有點(diǎn)拗口,但邏輯很簡(jiǎn)單:讓obj“繼承于”object!很好,我們看到了繼承,但你肯定會(huì)問,對(duì)象的繼承,第一次聽說啊,我們講繼承都是講的類的繼承。沒錯(cuò),現(xiàn)在的確還沒有看到真正的類繼承,但已經(jīng)近在眼前了:類不就是有個(gè)prototype嗎,而prototype是對(duì)象!
好,想到這一點(diǎn),類的繼承語法看似很簡(jiǎn)單了:
b.prototype.extend(a.prototype);
讓b繼承a。
可是事實(shí)卻沒那么簡(jiǎn)單:prototype是存放方法原型指針,extend方法沒有初始化,不能使用!要使用extend,就必須實(shí)例化一個(gè)對(duì)象。還是看看prototype是怎么做的吧:
b.prototype=(new a()).extend(b.prototype);
很高明的辦法!充分說明了函數(shù)其實(shí)也是一個(gè)變量的道理。先實(shí)例化a對(duì)象,然后在它基礎(chǔ)上調(diào)用extend,將所有的成員b.prototype的成員覆蓋到a的對(duì)象,然后把這個(gè)a對(duì)象再賦值給b.prototype。完成了b從a繼承的工作。在實(shí)際使用中,一般的用法都是:
b.prototype=(new a()).extend({});
因?yàn)樽屢粋€(gè)b繼承自a,通常b之前都是一個(gè)未定義的類,所以后面的{}中其實(shí)就可以定義類成員。當(dāng)然,你也可以先定義,再繼承,只是和傳統(tǒng)概念有所區(qū)別了。
OK,今天寫到這里很累了,估計(jì)看的人也是,呵呵?,F(xiàn)在我們基本明白了prototype的類開發(fā)框架,可以看一些高級(jí)應(yīng)用了,下回合再見:)
復(fù)制代碼 代碼如下:

<script language="javascript">
//給Object對(duì)象增加靜態(tài)方法extend,該方法的作為復(fù)制source有所有屬性和方法到destination
Object.extend = function(destination, source) {
for (property in source) {
destination[property] = source[property];
}
return destination;
}

var dog = function(name)
{
this.name = name;
}
//將printName方法復(fù)制給dog.prototype
Object.extend(dog.prototype,
{
printName:function()
{
alert(this.name);
}
}
);
var a = new dog("dog");
a.printName();
</script>

相關(guān)文章

最新評(píng)論