使用Ext.extend進行繼承的一個有趣的問題
在Ext的使用過程中,偶然發現了一個有趣的問題, 和大家共享一下。 先看如下代碼:
// 定義一個基類, 一個數組成員arr,和一個空函數init var BaseClass = Ext.extend(Ext.util.Observable, { arr: [], init: Ext.emptyFn }); // 定義一個子類,繼承自BaseClass,并重寫init方法, 向數組arr中添加一個1 var SubClass1 = Ext.extend(BaseClass, { init: function() { this.arr.push(1); } }); // 再定義一個子類, 也繼承自BaseClass,并重寫init方法, 向數組arr中添加一個2 var SubClass2 = Ext.extend(BaseClass, { init: function() { this.arr.push(2); } }); function extTest() { var c1 = new SubClass1(); c1.init(); alert(c1.arr); // 這里得到的應該是1, 結果也確實是1, 沒錯 var c2 = new SubClass2(); c2.init(); alert(c2.arr); // 這里得到的應該是一個2, 但是實際結果卻是1,2 ,有趣的問題出現了 }
在執行extTest函數時,收到的兩個alert分別是1和1,2 ,而且,如果不斷的執行extTest函數,得到的值會不斷的增加, 這是什么原因呢?問題肯定是處在Ext.extend方法上,加載debug版本的腳本, 對這個方法進行單步跟蹤,發現最終問題出現在Ext.override函數上, 看圖:
看來在那個for循環之中,只是將overrides中的各個屬性進行簡單賦值操作, 但是,對于本例中出現的數組, 賦值只能傳遞對數組的引用, 也就是說SubClass1和SubClass2將共享一個數組,因為他們引用的是同一個數組,怪不得得到的結果會與期望的不一致呢。
當然, 對于上面的代碼適當進行修改, 既可以得到預期的值
var BaseClass = Ext.extend(Ext.util.Observable, { arr: null, init: function() { this.arr = []; // init arr here. } }); var SubClass1 = Ext.extend(BaseClass, { init: function() { SubClass1.superclass.init.call(this); // call base class 's init function this.arr.push(1); } }); var SubClass2 = Ext.extend(BaseClass, { init: function() { SubClass2.superclass.init.call(this); // call base class 's init function this.arr.push(2); } }); function extTest() { var c1 = new SubClass1(); c1.init(); alert(c1.arr); var c2 = new SubClass2(); c2.init(); alert(c2.arr); }
雖然這只是一個很小的問題,但是卻不容忽視,我就犯了一個這樣的“錯誤”,郁悶了好長時間才發現原因, 因此給大家提個醒。
張志敏所有文章遵循創作共用版權協議,要求署名、非商業 、保持一致。在滿足創作共用版權協議的基礎上可以轉載,但請以超鏈接形式注明出處。
本博客已經遷移到 GitHub , 圍觀地址: https://beginor.github.io/
浙公網安備 33010602011771號