JS中除null和undefined幾乎都存在可讀屬性prototype和constructor矫户,且默認(rèn)情況下prototype屬性中還包含一個(gè)指向超類(lèi)constructor屬性的對(duì)象。
JS中所有的對(duì)象有一個(gè)prototype屬性和constructor银舱,默認(rèn)下瘪匿,prototype指向Obejct{}或functionName{}或者繼承的超類(lèi)。這里要注意的是null和undefined沒(méi)有prototype屬性或者至少是不可讀的寻馏。
這里我想先說(shuō)明一個(gè)問(wèn)題棋弥。JS中的類(lèi)沒(méi)有如PHP、Java或者C++中的private等可見(jiàn)性诚欠,雖然private等本身被作為關(guān)鍵字保留了顽染,但并沒(méi)有實(shí)際的應(yīng)用。另外JS中對(duì)象方法(或類(lèi)方法)的定義有兩種方式:
function A(){}
function B(){}
A.a1=function(){....}
A.prototype.a2=function(){.....}
兩者的區(qū)別表現(xiàn)在繼承上轰绵,如果B繼承A時(shí)只用B.prototype=A粉寞,那么B實(shí)際上只得到了a1方法;如果B繼承時(shí)只用B.prototype=A.prototype左腔,那么B實(shí)際上只得到了a2方法唧垦。且通過(guò)后者的方式instanceof判斷 B instanceof A時(shí)會(huì)返回True。實(shí)際使用時(shí)需要根據(jù)情況的需要使用液样。
因?yàn)橥ㄟ^(guò)prototype屬性业崖,我們可以方面的構(gòu)造或繼承類(lèi),所以在實(shí)際使用中必然會(huì)產(chǎn)生OOP的經(jīng)典問(wèn)題類(lèi)型檢測(cè)(或is_like問(wèn)題)蓄愁。雖然JS中的typeof可以判斷出對(duì)象的類(lèi)型双炕,但對(duì)這個(gè)需求沒(méi)有幫助。instanceof的檢測(cè)撮抓,左邊是要檢測(cè)的對(duì)象妇斤,右邊是要判斷的prototype屬性,它可以判斷出類(lèi)的繼承關(guān)系丹拯。比如
function A(){}
function B(){}
function C(){}
function O(){}
A.prototype = O.prototype;
B.prototype = A.prototype;
C.prototype = B.prototype;
那么instanceof對(duì)于 new A() instanceof O站超、new B() instanceof O、new C() instanceof B都會(huì)給出Ture的返回乖酬。但問(wèn)題在于JS默認(rèn)的所有對(duì)象的prototype都最終指向Object.prototype死相,所以他對(duì)我們的幫助極其有限。這時(shí)constructor可以幫助我們咬像。
constructor屬性在JS中同prototype一樣是普遍存在算撮,默認(rèn)下,constructor指向內(nèi)置類(lèi)型方法或者function Function(){[native code]} 或 function Object(){[native code]}县昂。同prototype一樣肮柜,null和undefined的constructor至少是不可讀的。從默認(rèn)的指向來(lái)看我們就能知道typeof實(shí)際上是對(duì)于自身constructor屬性的驗(yàn)證倒彰。
JS中prototype中還存在一個(gè)不可枚舉的屬性constructor审洞,我們就是靠利用這點(diǎn)來(lái)正確的判斷對(duì)象的實(shí)際構(gòu)造者的。如
function A(){}
function B(){}
function C(){}
A.prototype={constructor:A,somefunc:....}
B.prototype=A.prototype;
C.prototype=B.prototype;
這時(shí)雖然instanceof的運(yùn)算依然是給出Ture待讳,但是當(dāng)我們比較C.prototype.constructor==B時(shí)會(huì)得到False芒澜,而C.prototype.constructor==A卻是Ture仰剿。這樣我們就能夠確認(rèn)C究竟是B還是A。當(dāng)然constructor除了也可以是一個(gè)獨(dú)立的對(duì)象痴晦,但即使執(zhí)行了new操作后也不能使用該對(duì)象中定義的方法南吮。
綜上,我們完全可以利用prototype.constructor來(lái)構(gòu)建基類(lèi)阅酪。