?? javascript的prototype(原型)方式實現.txt
字號:
CSDN - 文檔中心 - 網站制作技術
標題 JavaScript的Prototype(原型)方式實現 liuruhong(原作)
關鍵字 JavaScript,Design Pattern,Prototype
寫在前面:
這是我前段時間和Jeff.Yan的一些討論搞,主要關于JavaScript的Design Pattern,因為沒有整理,都是最原始的email內容,我會陸續的貼出一點我給他信,至于他的一些回答和討論的結果,我會在征求他本人意見的情況下,盡可能完整的貼出來
因為是和Jeff.Yan的討論稿,對于我發信內容的發表都同時署名,對于他給我的回信,如果征得他本人同意的情況下在文字中我依然會特別說明。
--------------------------------------------------------------------------------
JavaScript的Prototype實現
作者:Jeff.Yan(閻宏),BlueSwing.Liu(劉如鴻)
模式:
Prototype(原始模型模式或者原型模式)
定義:
通過給出一個原型對象來指明所要創建的對象的類型,然后用這個原型對象的方法創建出更多同類型的對象,原始模型模式屬于對象的創建模式
JavaScript實現:
在Java語言中對象都繼承自java.lang.Object,而java.lang.Object就提供了Clone的方法,只要實現接口Cloneable,即表示支持Clone,否則拋出異常。在這點JavaScript是非常接近的,所有的對象都是從Object繼承,不過Object并不支持Clone的方法,但是我們可以通過自己對于JavaScript通過expanddo的形式實現Clone方法,這樣日后所有的對象創建都實現了Clone方法。
因為JavaScript本身沒有提供Clone的方法,同時對于對象的賦值如var a=new Object();var b=a,這樣的代碼a,b是指向同一對象的,要創建一個對象必須通過new 這個關鍵字來實現,因此在Clone的實現過程,我內部定義了一個構造子(constructor)CloneModel,同時指定其父對象為要進行Clone活動本身的對象,因此使用了this關鍵字,在我們定義的構造子CloneModel的基礎上我們創建一個一個對象,因為構造子內部沒有任何代碼,新創建的對象實際上說所有的實現都在父對象中,也就是我們需要進行Clone的對象。到目前為止,我們已經創建了一個需要復制的對象,但是所有的值都是指向父對象的。
在 JavaScript的面向對象方式中 ,我們曾經討論過,如果沒有覆蓋父對象的值,那么這個時候是直接指向父對象的,在Prototype Pattern是要求Clone之后的對象的內部值是不應該相關的,而只要賦值一次,objClone的值都會在自己的內存空間里頭,而不是還指向父對象。基于如此的考慮,objClone[v]=objClone[v];語句就是實現將父對象的值通過覆蓋的方式拷貝到自己的內存來。(這里提及的內存應該是邏輯意義上的)
深復制的實現
在完成上述工作之后,只是實現了淺復制,對象方面依然是指向對象的引用,這個時候可以通過調用指向對象的Clone方法得到cloned對象的屬性對象(因為不知道如何說了)。objClone[v]=objClone[v].Clone(); 這句代碼就是完成如此的功能。
Clone方法的實現
//////////////////////////////////////////////////////////////////////
//為Object添加Clone的方法,因為所有的對象的頂級對象都是Object
//因此所有用戶自定義對象都實現了Clone的方法
//////////////////////////////////////////////////////////////////////
Object.prototype.Clone=function(){
function CloneModel(){
}
CloneModel.prototype=this;
var objClone=new CloneModel();
var strMsg="";
for( v in objClone){
switch (typeof objClone[v]){
case "function":
//如果是方法,不需要進行clone
break;
case "object":
///////////////////////////////////////////////////////////////////////
//如果是對象,采用Clone重新得到,這樣做的目的在于能夠進行深度Clone
//因為JavaScript是一個Object Based的語言,不然內部對象是指向原來的引用
///////////////////////////////////////////////////////////////////////
objClone[v]=objClone[v].Clone();
break;
default:
///////////////////////////////////////////////////////////////////////
//其余數據類型情況下全部重新賦值
//這樣做的目的就是保證數值在內存中的存放是在新對象的空間中
//而不僅僅指向Parent Object的一個refrence
///////////////////////////////////////////////////////////////////////
objClone[v]=objClone[v];
}
}
return objClone;
}
對象類的定義
function BookInfo(vCaption){
this.Caption=vCaption;
var curPage=0;
this.setPage=function(vData){
curPage=vData;
}
this.getPage=function(){
return curPage;
}
}
測試代碼
//////////////////////////////////
//test BookInfo 's clone method
//
//////////////////////////////////
function test(){
var objTest=new BookInfo("JavaScript Prototype Pattern");
objTest.setPage(1000);
objTest.Author="Ruhong.Liu"; //object expanddo
ShowObject(objTest,"原始對象");
//Clone Object from objTest
var objCloned=objTest.Clone();
ShowObject(objCloned,"Clone之后的對象");
//if you changed the objTest's caption
//you can find objCloned's caption has be changed
objTest.Caption="Changed Base Object";
//show message
ShowObject(objTest,"修改Caption之后的原始對象");
ShowObject(objCloned,"修改Caption之后的clone對象");
/*
//----------這段代碼可以不工作------------------------//
//now you can change objCloned's caption
objCloned.Caption="hello,Jeff.Yan";
//show message
ShowObject(objTest,"Clone對象Caption修改之后的原始對象");
ShowObject(objCloned,"Clone對象Caption修改以后");
*/
}
function ShowObject(o,vCaption){
var strMsg=vCaption +"\n";
strMsg+="CurrentPage: " + o.getPage() +"\n";
strMsg+="Caption: " + o.Caption +"\n";
strMsg+="Expanddo Property Author: " + o.Author;
alert(strMsg);
}
--------------------------------------------------------------------------------
結束語:
按照我目前的理解和測試,我覺得prototype關鍵字不是prototype模式的實現,這點通過parent object可以得到驗證。
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -