2 回答

TA貢獻1條經驗 獲得超0個贊

TA貢獻1770條經驗 獲得超3個贊
1:首先,為什么這個的constructer要指向subType?
實例化一個對象的時候,會產生一個指針屬性:_protol_,指向實例的原型對象。我們的原型對象內會產生constructor屬性,指向它的構造函數。
我們的實例能從原型對象上繼承屬性與方法。同時,我們原型對象內的constructor屬性自然也能夠繼承到。
現在來看問題中的例子:
if(typeof(AbstractFac[superType]) == 'function'){ function F(){} F.prototype = new AbstractFac[superType](); console.log(subType); console.log(subType.constructor); }else{ throw new Error('null'); }
在重新指定constructor和進行繼承前來看看 傳入的subType 和 它的構造函數是什么:
function(price,speed){ this.price = price; this.speed = speed; }function Function() { [native code] }
即我們下面傳入子類的構造函數,此時的子類還沒有實例化,所以它還并沒有從其原型對象上獲取到constructor屬性。
此時,
subType : 我們定義的子類函數
subType.constructor(即一個函數的構造函數): 當然就是我們的Function對象了!
那么我們的抽象工廠為了創建出這個子類實例,需要做什么呢?
也就是例子中寫的啦:
subType.constructor = subType; subType.prototype = new F();
這樣一來,我們定義的未實例化的子類函數,通過這個抽象工廠,進行了實例化;通過subType.constructor = subType得到了本身應該有的constructror屬性,通過原型繼承到了父類的屬性和方法。
2:為什么要弄個F函數來緩存?
因為數組,對象,函數(方法),作為引用類型,它們的名稱只是指向堆內存的指針。如果直接subType.prototype = new AbstractFactory[superType]();那么我們可以通過子類去修改堆內存中的內容。進而改變父類的引用類型的值了。
緩存的話,能夠 阻止我們的子類對父類可能發生的更改。
添加回答
舉報