天天躁日日躁狠狠躁AV麻豆-天天躁人人躁人人躁狂躁-天天澡夜夜澡人人澡-天天影视香色欲综合网-国产成人女人在线视频观看-国产成人女人视频在线观看

Javascript的構造函數和constructor屬性

例如,在Chrome下調試如下程序,很清楚的展示了這點:

image 

然而事情并不是這么簡單。再看下面的代碼:

image
很顯然,這個時候obj的constructor已經不再是創建它的函數,注意到obj.name也是undefined,因此修改構造函數的prototype的contructor并不會影響構造函數所產生的對象。真正的原因是:一個對象的constructor是它的構造函數的prototype.constructor,而每一個函數都有一個prototype,默認情況下,這個prototype有一個constructor屬性,指向的是它自己。 我覺得Javascript的設計本意是讓每個對象的constructor都指向自己的構造函數,然而有像上面的例子可以破壞這一點。另外,這樣的設計其實也不很完美,一個很大的問題就是在繼承的時候必須小心的維護constructor的指向。在最簡單的繼承中,可以把子類的構造函數的prototype設置為父類的一個實例,而父類的實例的constructor是父類的構造函數,從而子類的prototype的constructor是父類的構造函數,這就造成了子類的每個對象的構造函數都是父類的構造函數。這是很容易引起困惑的。

最后,再回到上一篇遺留下來的問題,上文談到Extjs官網給出的一個繼承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)
}
});

這個例子給人的錯覺就是你可以重寫父類的constructor屬性,從而達到改變子類的構造函數的行為的效果。這對于Javascript基礎卻不深的人是一種誤導。 我們再仔細看下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);}; //注意這里 }
//以下省略………}(), 請注意加注釋的那一行。extend如果檢測到overrides參數中有constructor屬性,也就是說子類試圖改寫父類的prototype的constructor的時候,就直接將子類設置為這個函數!這樣就達到效果了。不過我立刻發現這句檢測僅在這個if語句塊中,也就是extend的兩參數版本中有,那么使用extend的另一個三參數版本這樣設置應該是無效的。 寫段代碼測試下:

<head>
<title></title>
<script type="text/Javascript" src="ext-3.1.0/src/core/core/Ext.js"></script>
<script type="text/Javascript">
function MyClass() {
this.id = 'class';
}
function SubClass() { }

// SubClass=Ext.extend(SubClass, MyClass, { constructor: function() {
// this.overrideProperty = 'OK';
// }
// });
SubClass = Ext.extend(MyClass, { constructor: function() {
this.overrideProperty = 'OK';
}
});
var obj = new SubClass();
alert(obj.overrideProperty);
</script>
</head>

兩種寫法,運行的結果果然是第一種是undefined而第二種是OK。呃,名字相同的函數僅僅是參數寫法不同,執行的效果卻不相同,這個是有點出乎意料的。而且Extjs的官方文檔未對此有任何說明。以后大家還是盡量用兩參數版本的吧。
最后順便再看幾個表達式,
image 
第一個是說函數的prototype的constructor是自己,這個上文已經談到,沒有問題;第二個是說函數也是一個對象,它是Function構造函數的一個對象,也還好理解;第三個是說Function構造函數本身一個對象,它還是Function構造函數的一個對象;最后一個其實是和第三個等價的,是說Function對象的構造函數是它自己…… 我確實有點想不明白Function是怎么自己構造自己的?雞生蛋,蛋生雞?要再追究下去就應該涉及到Javascript語言的具體實現了吧,就此打住。

哎,Javascript這個語言本身還是有點復雜啊。要不是有了XMLHttpObject,讓它大紅大紫了下,否則它還在黑暗的角落里暗自哭泣呢。

作為應用程序開發人員,或許我們自己寫程序的并不會用到這些底層的東西,但是,JS框架中卻大量的使用了這些高級特性,而且再詳盡的文檔也不可能把這些方法的作用、影響一一道來,所以開發人員還是需要盡量理解這些東西,以免死了還不知道怎么回事。上面的Ext.extend函數就是一個例子。

JavaScript技術Javascript的構造函數和constructor屬性,轉載需保留來源!

鄭重聲明:本文版權歸原作者所有,轉載文章僅為傳播更多信息之目的,如作者信息標記有誤,請第一時間聯系我們修改或刪除,多謝。

主站蜘蛛池模板: 国产精品久久久久久精品... | fryee性欧美18 19 | 成人在线免费视频播放 | av影音先锋影院男人站 | 国产精品网红女主播久久久 | 99re久久热在线播放8 | 午夜黄视频 | 被老师按在办公桌吸奶头 | 久久天堂网 | 白丝制服被啪到喷水很黄很暴力 | 国产在线视频一区二区不卡 | 中文字幕日本在线mv视频精品 | 毛片网站在线观看 | 97精品一区二区视频在线观看 | 2021扫黑风暴在线观看免费完整版 | 国产曰韩无码亚洲视频 | 精品国产乱码久久久久久免费流畅 | YELLOW高清视频免费观看 | 三级黄色在线观看 | 成人性视频全过程 | 亚洲日韩视频免费观看 | 四虎影视国产精品亚洲精品hd | 无码人妻99久久密AV | 综合色一色综合久久网vr | 亚洲精品拍拍央视网出文 | 欧洲另类一二三四区 | 穿白丝袜边走边尿白丝袜 | 色偷偷av男人的天堂 | 一本色道久久88加勒比—综合 | 国产亚洲精品久久播放 | 亚洲人成影院在线播放 | 亚洲444777KKK在线观看 | 亚洲AVAV天堂AV在线网爱情 | 97精品国产自产在线观看永久 | 男人到天堂a线牛叉在线 | 黄小说免费看 | 天天夜夜草草久久亚洲香蕉 | XXX国产麻豆HD | 国产成人在线播放视频 | 精品日韩欧美一区二区三区 | 久久视频在线视频观看天天看视频 |