其實在工作中使用原型繼承非常簡單,只是為構(gòu)建函數(shù)的prototype屬性(這個屬性本身就是一個對象)添加想要的方法,然后通過此構(gòu)建函數(shù)new出來的實例就都可以使用這些方法了。
(構(gòu)建函數(shù)與普通函數(shù)的區(qū)別也很簡單,構(gòu)建函數(shù)是一個函數(shù)初始化的過程,沒有返回值;普通函數(shù)一般都是為了服務(wù)于某功能所以一般都會返回某個值,如果執(zhí)行一個沒有返回值的函數(shù)會得到undefined的結(jié)果,而如果對一個有返回值的函數(shù)執(zhí)行new的操作則會報錯此函數(shù)不是構(gòu)造函數(shù))。
此處作總結(jié)是因為雖然工作上要使用原型繼承很簡單,但是面試時面試官問到這個時要回答起來比較麻煩,所以總結(jié)一下這題目里的這兩個屬性。
首先是除了函數(shù)外,任何一個對象都自帶_proto_這個屬性,這個屬性的初始化會指向?qū)ο蟮脑偷膒rototype屬性。
也就是var a=new B();的時候,實際上會在實例化a的同時,執(zhí)行a._proto_=B.prototype;的過程,于是當(dāng)在a上面訪問某個方法時,如果a本身沒有這個方法,就會去找a._proto_,由于它指向了B.prototype,然后就在B.prototype上面找了,然后由于任何對像都自帶_proto_屬性的,如果在B.prototype身上還沒找到對應(yīng)方法,就會去找B.prototype._proto_,然后再找下一層(此時一般是之前就對B.prototype進(jìn)行了其他賦值,如B.prototype=C.prototype,或者B.prototype=D{},又或者B.prototype=new C()這樣的操作,才有下一步,否則就已經(jīng)到Object.prototype了),一直找到Object.prototype,如果還是沒找到,就返回undefined;
至于prototype屬性(這是一個對象),它只存在于函數(shù)(包括普通函數(shù)與構(gòu)建函數(shù))以及Object身上,其他類型的數(shù)據(jù)是沒有的,比如函數(shù)的實例化是沒有的:var p=new B();p.prototype為undefined;
(其實就是每個對像身上都有一個用于實現(xiàn)繼承的屬性,在函數(shù)身上是prototype,在其他數(shù)據(jù)身上是_proto_,有prototype的不會同時出現(xiàn)_proto_,反之亦然)