[javascript]圖解+注釋版 Ext.extend()

來源:互聯網
上載者:User

Ext.extend() 體現了程式員非凡的製造輪子的能力。它基於 javascript 古老的物件模型,最大程度地類比出現代物件導向語言的類型繼承的語意。但是在程式界有太多的“與XXX很像”,但是實際上又有很多差別。要想最徹底、最精確地理解 Ext.extend(),最直接(往往也是最有效)的方法就是去讀它的原始碼。為了達到更好的可讀性,我更改了部分變數名稱,加上了詳細的注釋。

  1 /**  2          * <p>Extends one class to create a subclass and optionally overrides members with the passed literal. This method  3          * also adds the function "override()" to the subclass that can be used to override members of the class.</p>  4          * For example, to create a subclass of Ext GridPanel:  5          * <pre><code>  6 MyGridPanel = Ext.extend(Ext.grid.GridPanel, {  7     constructor: function(config) {  8   9 //      Create configuration for this Grid. 10         var store = new Ext.data.Store({...}); 11         var colModel = new Ext.grid.ColumnModel({...}); 12  13 //      Create a new config object containing our computed properties 14 //      *plus* whatever was in the config parameter. 15         config = Ext.apply({ 16             store: store, 17             colModel: colModel 18         }, config); 19  20         MyGridPanel.superclass.constructor.call(this, config); 21  22 //      Your postprocessing here 23     }, 24  25     yourMethod: function() { 26         // etc. 27     } 28 }); 29 </code></pre> 30  * 31  * <p>This function also supports a 3-argument call in which the subclass's constructor is 32  * passed as an argument. In this form, the parameters are as follows:</p> 33  * <div class="mdetail-params"><ul> 34  * <li><code>subclass</code> : Function <div class="sub-desc">The subclass constructor.</div></li> 35  * <li><code>superclass</code> : Function <div class="sub-desc">The constructor of class being extended</div></li> 36  * <li><code>overrides</code> : Object <div class="sub-desc">A literal with members which are copied into the subclass's 37  * prototype, and are therefore shared among all instances of the new class.</div></li> 38  * </ul></div> 39  * 40  * @param {Function} superclass The constructor of class being extended. 41  * @param {Object} overrides <p>A literal with members which are copied into the subclass's 42  * prototype, and are therefore shared between all instances of the new class.</p> 43  * <p>This may contain a special member named <tt><b>constructor</b></tt>. This is used 44  * to define the constructor of the new class, and is returned. If this property is 45  * <i>not</i> specified, a constructor is generated and returned which just calls the 46  * superclass's constructor passing on its parameters.</p> 47  * <p><b>It is essential that you call the superclass constructor in any provided constructor. See example code.</b></p> 48  * @return {Function} The subclass constructor from the <code>overrides</code> parameter, or a generated one if not provided. 49  */ 50 Ext.extend = function(){ 51     // inline overrides 52     var io = function(o){ 53         for(var m in o){ 54             this[m] = o[m]; 55         } 56     }; 57     var oc = Object.prototype.constructor; // 如果一個對象的 constructor == oc,說明它是使用類似 { age:22 } 這種文法建立的字面量對象, 58                                            // 而且沒有對constructor屬性賦值 59  60     return function(subClass, superClass, overrides){ 61         if(typeof superClass == 'object'){ 62             // 如果 superClass 是對象而不是建構函式,就說明是使用的是 63             // var Cat = Ext.extend(Animal, { 64             //     say : function() { 65             //         document.writeln("I'm a cat name " + this.name); 66             //     } 67             // }); 68             // 這種方式調用的。也就是說傳回值是subClass, subClass 參數其實是 superClass,superClass參數其實是overrides,overrides參數應該被忽略 69             overrides = superClass; // 忽略 overrides 參數 70             superClass = subClass; // subClass 參數其實是 superClass 71             // subClass 參數將作為將來的傳回值。 72             // 如果 overrides 對象沒有自訂建構函式,為其定義一個,並且裡面調用父類建構函式; 73             // 如果 overrides 對象含有自訂建構函式,把overrides的建構函式賦給子類 74             subClass = overrides.constructor != oc ? overrides.constructor : function(){  75                     superClass.apply(this, arguments); // 調用父類建構函式(前提是子類建構函式的參數可以比父類少,但是順序要一致) 76                 }; 77         } 78          79         // 原型式繼承。之所以建立一個臨時建構函式F,而不是令 subClass.prototype = new SuperClass, 80         // 是為了更改子類的prototype的時候不會影響到父類的prototype 81         var F = function(){}, 82             subPrototype, // 子類建構函式的 Prototype 83             superPrototype = superClass.prototype; // 父類建構函式的 Prototype  84  85         F.prototype = superPrototype; 86         subPrototype = subClass.prototype = new F(); 87         subPrototype.constructor=subClass; 88         // 只所以沒寫成 subClass.superclass=superClass,是為了在overrides對象的constructor方法裡 89         // 可以使用諸如 “MyGridPanel.superclass.constructor.call(this, config)”這種(讀起來比較 90         // 自然的)寫法調用父類建構函式。 91         subClass.superclass=superPrototype; 92         // 如果 superclass.prototype 是字面量對象,確保 superclass.prototype。constructor 指向 superClass 93         if(superPrototype.constructor == oc){ 94             superPrototype.constructor=superClass; 95         } 96         // 為子類增加一個override()方法。調用 subClass.override(o) 等價於調用 Ext.override(subClass, o) 97         subClass.override = function(o){ 98             Ext.override(subClass, o); 99         };100         // 增加一個名為 superclass() 的執行個體方法,這樣在overrides對象的constructor方法裡101         // 就可以使用諸如 “this.superclass().constructor.call(this, config)”來調用父類102         // 建構函式,而且沒有依賴子類建構函式的名稱。103         subPrototype.superclass = subPrototype.supr = (function(){104             return superPrototype;105         });106         // 為子類增加一個執行個體方法: override()107         subPrototype.override = io;108         // 將 overrides 對象裡的方法複寫到 subClass.prototype 中109         Ext.override(subClass, overrides);110         // 為子類增加一個extend()方法。調用 subClass.extend(o); 等價於調用 Ext.extend(subClass, o);111         subClass.extend = function(o){return Ext.extend(subClass, o);};112         return subClass;113     };114 }();

下面這張對象圖則是執行了 var SubClass = Ext.extend(SuperClass, { someprop : 'some' }) 之後的效果。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.