在YUI的繼承模式3
2010年1月6日6:30上午斯托揚STEFANOV | 開發 | 2評論
作者簡介:: 斯托STEFANOV ( @ stoyanstefanov )是在雅虎搜索的前端工程師。 他也是YSlow的2.0 smush.it形象優化,揚聲器和技術作家共同創作的建築師。 他的最新著作被稱為面向對象的JavaScript 。
本文討論了兩個JavaScript代碼重用的格局,在實施銳3 -經典的遺傳模式和原型繼承模式。
令人滿意的依賴
原型模式是從核心銳3 API在YUI-min.js種子的文件。 經典模式需要oop模塊,但自從oop模塊是其他模塊的要求,你通常不會有做什麼特別的東西來獲得此功能。 但如果你想創建一個簡單的測試頁,發揮自己的模式,你能滿足的依賴,像這樣由包括銳:
<script type="text/javascript" src="http://yui.yahooapis.com/3.0.0/build/yui/yui-min.js"> </ SCRIPT> <SCRIPT> YUI的()。使用(“空中接力”,功能(Y){ / /你的代碼放在這裡 / / Y是YUI的實例 }); </ SCRIPT>
(偽)經典的繼承
你可以調用這個模式的“經典”不是,因為它從柏拉圖的古希臘,但因為它有助於你認為類。 JavaScript沒有類(因此“偽”的一部分),但它的構造函數,而不是。
在Java或其他語言,你可以從Programmer Person Person類有一個Programmer類繼承。 在JavaScript中,你實際上有一個Programmer的構造函數和Person Person的構造函數。 我們的目標是有創建的對象的Programmer構造繼承的屬性和方法,如果他們與Person的構造。
考慮這兩個構造函數:
/ /父 功能的人(){ / /“自己”的成員 this.name =“亞當”; } / /屬性的父的原型 Person.prototype.getName =函數(){ 返回this.name; }; / /孩子的構造 函數編程(){}
YUI的3 oop模塊的提供的Y.extend(...)的方法來幫助你繼承遺產的一部分。 它是那樣簡單:
y.extend(程序員,人); 然後,您可以測試getName()方法是正確的繼承:
VAR大師=新程序員(); 提醒(guru.getName typeof運算); / /“功能”
需要注意的是, Y.extend(...)方法只會繼承的原型,而不是“自己”的成員。 它被認為是一個很好的做法,添加所有可重複使用的功能樣機,並留下自己的屬性(添加到所有的實例特定的屬性this 。 在上面的例子中,唯一getName()得到繼承,而name不。 (在你的原型繼承模式 - 在文章中進一步討論 - 繼承原型和自己的成員。)
延伸和補充
Y.extend(...)允許你從一個父類的構造函數和同時增加新成員的孩子繼承。 其實,這是事實上的模式由銳用於建立“類”擴展。
您可以添加屬性到孩子的構造函數的原型,使用第三個參數Y.extend(...)你可以添加屬性的構造本身(類的靜態屬性)使用第四個參數。
下面是一個在同一時間的延長和充實的例子:
y.extend(程序員,人,{groksHTML:真},{極限:“天空”}); / / groksHTML的,現在是一個孩子的原型屬性 提醒(Programmer.prototype.groksHTML typeof運算); / /“布爾” / /屬性適用於所有新對象 VAR鮑勃=新程序員(); 警報(bob.groksHTML); / /真 / /添加到構造更適合 / /“靜態”屬性意味著作為常數 警報(Programmer.LIMIT); / /“天空” VAR限制bob.LIMIT; / /未定義
超
以上所述的pseudoclassical模式,讓你進入superclass通過靜態的屬性稱為父類的構造原型。
superclass家長和原型點superclass.constructor點的父構造函數。 考慮一個例子:
/ /繼承 y.extend(程序員,人); / /孩子的訪問父類的構造函數 父= Programmer.superclass.constructor; / /測試 警報(父===人); / / TRUE / /訪問父,從孩子的一個實例 VAR大師=新程序員(); guru.constructor.superclass.constructor ===人; / /真
如前所述,與傳統的模式,你只能繼承原型成員。 但使用的superclass也可以從孩子的父類的構造函數初始化和得到父母的孩子自己的屬性自己的屬性。
你可以修改Programmer構造調用父類的構造函數,傳遞的子對象( this )和任何初始化參數
/ / ... 父定義一樣顯示之前... / /子 函數編程(){ / /初始化父“本”的孩子 Programmer.superclass.constructor.apply(這一點,參數); } / /繼承 y.extend(程序員,人); / /測試 VAR親=新程序員(); 警報(pro.name); / /“亞當”
正如你可以看到,現在的編程實例有name name屬性,這是一個自己的財產。
警報(pro.hasOwnProperty('名稱')); / / TRUE 警報(pro.hasOwnProperty('的getName')); / /假
訪問覆蓋的方法
事實上, superclass到父原型重寫的方法讓孩子獲得。 考慮這個典型的例子,繼承Triangle Shape Triangle :
/ /父 函數的形狀(){} Shape.prototype.toString =函數(){ 返回“形”; }; / /子 函數三角(){} / /繼承 y.extend(三角形狀); / /子覆蓋父的toString()方法 / /但由於超類的屬性 / /它仍然有原來的方法 Triangle.prototype.toString =函數(){ 返回Triangle.superclass.toString()+“三角”; }; / /測試 VAR急性=新三角(); “形,三角”acute.toString();
原型繼承
道格拉斯克羅克福德表明,這種繼承模式,你忘了所有關於類和對象從其他對象繼承。 例如:
/ /父對象,創建一個簡單的對象字面 VAR父= { 名稱:“約翰” 家人:“韋恩”, 說:(){ 回到“我”+ this.name +“”+ this.family; } }; / /繼承魔 / /一個新的對象是從現有的出生 VAR蝙蝠俠,= Y.Object(母公司); / /自定義或增加新的對象 batman.name =“李小龍”; / /使用 batman.say(); / /我是布魯斯·韋恩
使用這種模式設立的對象有兩個步驟:
- 你創建一個新的對象,繼承從現有對象的屬性和方法。
- 您可以自定義新的對象 - 可以覆蓋一些成員或添加新的品牌。
請注意, Y.Object(...)是在YUI核心。 你不必包括oop模塊。
原型繼承討論
如果你好奇的原型繼承背後的動機,以及它如何引擎蓋下,你可以學習模式中描述的Douglas Crockford的自己的話 。
使用這種模式,通過原型鏈繼承父的成員。 這意味著,如果添加具有相同名稱的子屬性,新的屬性不會覆蓋從父項繼承的,但它會優先考慮。 換句話說,你可以重新定義的say ,像這樣的方法:
batman.say =函數(){ 返回“無法告訴你我的真實姓名”; }; / /測試 batman.say(); / /“不能告訴你我的真實姓名”
不像在經典遺傳模型,給予Y.extend ,有沒有辦法來引用父say從子對象的方法say (vis. superclass )。 不過,如果你刪除的say子對象的方法,父母的say將“閃耀通過”。
刪除batman.say; batman.say(); / /“我是布魯斯·韋恩”
在ECMAScript 5
ECMAScript標準的新版本,包括通過本地方法稱為原型及繼承格局Object.create(...)
/ / YUI3 VAR蝙蝠俠,= Y.Object(母公司); / /的ECMAScript 5(未來) VAR蝙蝠俠= Object.create(父);
更多?
非常感謝您的閱讀! 在這篇文章中討論的兩種模式的更多信息和例子,你可以參考以下鏈接:
請繼續關注為後續的文章,討論YUI3甚至更多的代碼重用的模式。
共享和擴展: 書籤del.icio.us Digg它! | reddit!
2評論
很抱歉,評論已被封閉,在這個時候。


[...]繼承模式在YUI的3 - 斯托揚STEFANOV著眼於兩個JavaScript代碼重用的模式(經典的繼承和原型繼承),在Yahoo! YUI的3庫實施,[...]
pingback的早晨BREW克里斯-阿爾科克»晨報BREW#512 - 1月7日,2010 #
[...]後的後續文章“YUI3繼承模式”和YUI3代碼重用模式的API潛入更深。 剛四書[...]
pingback的更多的代碼於YUI3»雅虎用戶界面博客(YUIBlog)的重用模式 - 1月7日,2010 #