然而事情并不是這么簡(jiǎn)單。再看下面的代碼:
很顯然,這個(gè)時(shí)候obj的constructor已經(jīng)不再是創(chuàng)建它的函數(shù),注意到obj.name也是undefined,因此修改構(gòu)造函數(shù)的prototype的contructor并不會(huì)影響構(gòu)造函數(shù)所產(chǎn)生的對(duì)象。真正的原因是:一個(gè)對(duì)象的constructor是它的構(gòu)造函數(shù)的prototype.constructor,而每一個(gè)函數(shù)都有一個(gè)prototype,默認(rèn)情況下,這個(gè)prototype有一個(gè)constructor屬性,指向的是它自己。 我覺(jué)得Javascript的設(shè)計(jì)本意是讓每個(gè)對(duì)象的constructor都指向自己的構(gòu)造函數(shù),然而有像上面的例子可以破壞這一點(diǎn)。另外,這樣的設(shè)計(jì)其實(shí)也不很完美,一個(gè)很大的問(wèn)題就是在繼承的時(shí)候必須小心的維護(hù)constructor的指向。在最簡(jiǎn)單的繼承中,可以把子類(lèi)的構(gòu)造函數(shù)的prototype設(shè)置為父類(lèi)的一個(gè)實(shí)例,而父類(lèi)的實(shí)例的constructor是父類(lèi)的構(gòu)造函數(shù),從而子類(lèi)的prototype的constructor是父類(lèi)的構(gòu)造函數(shù),這就造成了子類(lèi)的每個(gè)對(duì)象的構(gòu)造函數(shù)都是父類(lèi)的構(gòu)造函數(shù)。這是很容易引起困惑的。
最后,再回到上一篇遺留下來(lái)的問(wèn)題,上文談到Extjs官網(wǎng)給出的一個(gè)繼承Observable的例子:
代碼如下:
Employee = Ext.extend(Ext.util.Observable, {
constructor: function(config){
this.name = config.name;
this.addEvents({
"fired" : true,
"quit" : true
});
// Copy configured listeners into *this* object so that the base class's
// constructor will add them.
this.listeners = config.listeners;
// Call our superclass constructor to complete construction process.
Employee.superclass.constructor.call(config)
}
});
這個(gè)例子給人的錯(cuò)覺(jué)就是你可以重寫(xiě)父類(lèi)的constructor屬性,從而達(dá)到改變子類(lèi)的構(gòu)造函數(shù)的行為的效果。這對(duì)于Javascript基礎(chǔ)卻不深的人是一種誤導(dǎo)。 我們?cè)僮屑?xì)看下Ext.extend的源代碼:
代碼如下:
extend : function(){
// inline overrides
var io = function(o){
for(var m in o){
this[m] = o[m];
}
};
var oc = Object.prototype.constructor;
return function(sb, sp, overrides){
if(Ext.isObject(sp)){
overrides = sp;
sp = sb;
sb = overrides.constructor != oc ? overrides.constructor : function(){sp.apply(this, arguments);}; //注意這里 }
//以下省略………}(), 請(qǐng)注意加注釋的那一行。extend如果檢測(cè)到overrides參數(shù)中有constructor屬性,也就是說(shuō)子類(lèi)試圖改寫(xiě)父類(lèi)的prototype的constructor的時(shí)候,就直接將子類(lèi)設(shè)置為這個(gè)函數(shù)!這樣就達(dá)到效果了。不過(guò)我立刻發(fā)現(xiàn)這句檢測(cè)僅在這個(gè)if語(yǔ)句塊中,也就是extend的兩參數(shù)版本中有,那么使用extend的另一個(gè)三參數(shù)版本這樣設(shè)置應(yīng)該是無(wú)效的。 寫(xiě)段代碼測(cè)試下:
聲明:本網(wǎng)頁(yè)內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問(wèn)題請(qǐng)及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com