更多的代碼重用的模式,在YUI3

2010年1月7日,6:41上午斯托揚STEFANOV | 開發 | 2評論

斯托揚STEFANOV。 作者簡介:: 斯托STEFANOV@ stoyanstefanov )是在雅虎搜索的前端工程師。 他也是YSlow的2.0 smush.it形象優化,揚聲器和技術作家共同創作的建築師。 他的最新著作被稱為面向對象的JavaScript

這是一篇文章“傳承模式的後續YUI3“潛入YUI3代碼重用模式的API更深。 四本書剛主張,我們應該“寧可對象組成的類繼承”。 而事實上,繼承有時被用來作為一個強類型語言在編譯時需要固定對象或類的簽名的解決方法。 JavaScript是鬆散類型和對象可以組成混合,並隨時增加。

充實的對象

在現實生活中的JavaScript,它是罕見的,你就必須設置深的繼承鏈。 通常情況下,你可能只是想不必然形成了親子關係,擴充現有的對象(或構造)的另一個成員。 YUI提供的的方法Y.augment(...)來做到這一點。

下面的例子說明之間的差異與正確的繼承Y.extend(...)用簡單的對象增強Y.augment(...)

 / /父,又名供應商的功能
函數編程(){}
 Programmer.prototype.writeCode =函數(){};

 / /構造函數得到增強與供應商的成員
功能CodeMonkey(){}
 Y.augment(CodeMonkey,程序員);
猴子=新CodeMonkey();

 / /構造函數的繼承從父供應商
功能大師(){}
 y.extend(師,程序員);
 VAR大師=新大師();

現在,我們已經重用Programmer在兩個方面的功能,讓我們的測試結果。 這兩個對象的monkeyguru得到writeCode()的方法,但只有guru是繼承鏈的一部分。

提醒(monkey.writeCode typeof運算); / /“功能”
提醒(guru.writeCode typeof運算); / /“功能”

 / /猴子是不是一個程序員,而大師是
警報(猴子的instanceof程序員); / /假
警報(大師的instanceof程序員); / / TRUE

Y.augment(...)也可以採取一個對象(而不是一個構造)被擴大。

 VAR n00b = {};
 Y.augment(n00b,程序員);

 / /現在,n00b可以writeCode
提醒(n00b.writeCode typeof運算); / /“功能”

Y.augment(...)允許收件人是從供應商的代碼重用時更挑剔。 一個可選的第三個參數Y.augment(...)定義現有的屬性是否應該覆蓋(默認情況下, false ,這意味著維護收件人的原始屬性)。 第四個參數,可以選擇提供一個白名單 - 一個數組,其中包含應結轉的屬性的名稱。

克隆

克隆的對象是另一個代碼的重用,它允許你創建全新的對象只是喜歡現有的格局。 在某種程度上,這個想法是類似的原型繼承(見Y.Object(...)在以前的文章),對象從對象繼承。 主要區別在於克隆時,父母的屬性被複製到孩子直接通過原型鏈。

Y.clone(...)創建了一個深拷貝,這意味著它通過數組和對象屬性的遞歸。 它還創建值的副本,使克隆的對象不修改錯誤(JavaScript數組,對象和功能參考複製)的母公司。

為了說明差異,考慮的對象pro ,被克隆到一個新的對象clone ,也繼承wiz使用Y.Object(...)

 / /原始對象
 VAR親= {groks:['HTML']};

 / /繼承
 VAR的WIZ = Y.Object(親);

 / /克隆
克隆= Y.clone(親);

現在讓我們添加一個新的數組元素的原始對象

 pro.groks.push(“CSS”);

子對象看到更新後的值,而克隆不會,因為克隆是快照克隆的對象是什麼。

 wiz.groks.join(); / /“HTML,CSS”
 clone.groks.join()/ /“HTML”

這個工程以及周圍其他方式 - 當孩子修改數組。

 wiz.groks.push(“JS”);
 pro.groks.join(); / /“HTML,CSS,JS”
 clone.groks.join()/ /“HTML”

克隆的討論

正如你可以看到Y.clone(...)創建新的對象深複製其所有的屬性和方法。 雖然這可能不是你通常會調用繼承,它仍然是一個非常簡單和直接的代碼重用的模式。 畢竟代碼重用是如何避免重複代碼需要和重用現有功能。

您可能想知道的東西 - 性能如何呢? 是不是這樣低效的複製值。 答案是 - 是,它可能是低效的。 但對於大多數應用程序很少會成為瓶頸。 事實上的Firebug (Firefox擴展是用JavaScript編寫的),這是一個相當複雜的軟件有一個extend()方法,通過簡單複製從父對象到子對象的屬性,使用淺拷貝(不遞歸到對象和數組)

因此,自克隆僅僅是從一個對象到另一個深拷貝的屬性,也不會是很好的,如果你可以從多個對象繼承的功能,不僅從一個呢? 這是Y.merge(...)來幫助你與這個組合的排序對象。

mixin的對象與Y.merge(...)

混入模式讓您可以抓取多個對象的屬性和方法,並進行他們進入一個新的對象。 YUI3提供的的方法Y.merge(...)可採取任何數量的對象,並返回一個單一的,這是一個所有源對象的組合。

下面是一個例子:

組合:= {VAR mad_skillz烘烤:函數(){}(){},吃:函數(){}};
 VAR成分= {糖:“很多”,麵粉:1,雞蛋:2};
 VAR =乳品{牛奶:1};

 / /混入
蛋糕= Y.merge(mad_skillz,配料,乳品);

現在你可以測試屬性已經結轉到cake對象,使用便捷的方法Y.Object.keys(...)讓你的所有屬性名稱陣列。

 (蛋糕)。Y.Object.keys加入(); / /“烤,拌,吃,糖,麵粉,蛋,奶”

Y.merge(...)類似於克隆,但深複製一個對象,而不是,它會創建一個淺表副本,並可以採取多種混合用同樣的方法調用的對象。 被覆蓋的邏輯Y.merge(...)在物業命名衝突的情況下比大多數其他方法是不同的-如果你有兩個相同的名字,最後一勝的成員,並覆蓋以前的。

只是想與Y.clone(...) Y.merge(...)不一定僅限於代碼重用的目的。 你也可以使用它們用於處理數組或哈希樣的對象,如配置對象,排序。

Y.mix(...)

Y.mix(...)是較低級別的方法背後最上面討論的功能。 它為您提供細粒度控制哪些屬性被複製和確切位置。 它還允許你合併兩個具有相同名稱的屬性,忽略某些屬性等。

下面是一個使用有點複雜的例子Y.mix(...)的API:

 / /對象
 VAR親= {
   groks:['HTML','CSS','JS'],
  者說:['拉丁'],
  鳴叫:真
 };

 / /構造函數
功能WebGuru(){}

 / /增強的構造原型
 / /與一些親的屬性
 y.mix(WebGuru,親,真實,['groks“,”鳴叫“,4);

 / /測試
 VAR大師=新WebGuru();
 guru.groks.join(); / /“HTML,CSS,JS”
 guru.tweets; / /真
 guru.speeks; / /未定義

如果您在通話中尋找到Y.mix(...)我們有5個參數,含義:

  1. WebGuru得到更多的成員...
  2. pro ...
  3. 覆蓋任何現有的...
  4. 只有當他們在這個白名單陣列['groks', 'tweets'] 這意味著將不會被混合speaks財產
  5. 四是模式。 有五個混合模式- 0至4,4表示的原型 WebGuru成員將收到來自pro

你可以檢查文檔上所接受的參數的更多信息Y.mix(...)

這是所有的人!

謝謝您的閱讀! YUI3 OOP的功能的更多信息和例子,你可以參考以下鏈接:

共享和擴展: 書籤del.icio.us Digg它! | reddit!

2評論

  1. 真的是很不錯的博客......實在是非常有益的了解原型與經典的繼承之間的差異。

    好一個......

    評論vishwa之友- 7月23日,2010

  2. 但如果你說“有五個混合模式 - 0至4,其中4表示WebGuru原型將收到來自親”,那麼,當我實例2 WebGuru,我在一個實例groks陣列的變化將體現在其他情況下,被複製的原型:S或我失去了一些東西?

    評論Totty - 2011年1月18日

很抱歉,評論已被封閉,在這個時候。

主辦雅虎

©2006-2012雅虎公司所有權利保留。 隱私政策 - 服務條款

支持WordPress的關於雅虎 虛擬主機