其實(shí)在工作中使用原型繼承非常簡單,只是為構(gòu)建函數(shù)的prototype屬性(這個(gè)屬性本身就是一個(gè)對象)添加想要的方法忽舟,然后通過此構(gòu)建函數(shù)new出來的實(shí)例就都可以使用這些方法了。
(構(gòu)建函數(shù)與普通函數(shù)的區(qū)別也很簡單,構(gòu)建函數(shù)是一個(gè)函數(shù)初始化的過程叮阅,沒有返回值刁品;普通函數(shù)一般都是為了服務(wù)于某功能所以一般都會返回某個(gè)值,如果執(zhí)行一個(gè)沒有返回值的函數(shù)會得到undefined的結(jié)果浩姥,而如果對一個(gè)有返回值的函數(shù)執(zhí)行new的操作則會報(bào)錯(cuò)此函數(shù)不是構(gòu)造函數(shù))挑随。
此處作總結(jié)是因?yàn)殡m然工作上要使用原型繼承很簡單,但是面試時(shí)面試官問到這個(gè)時(shí)要回答起來比較麻煩勒叠,所以總結(jié)一下這題目里的這兩個(gè)屬性兜挨。
首先是除了函數(shù)外,任何一個(gè)對象都自帶_proto_這個(gè)屬性眯分,這個(gè)屬性的初始化會指向?qū)ο蟮脑偷膒rototype屬性拌汇。
也就是var a=new B();的時(shí)候,實(shí)際上會在實(shí)例化a的同時(shí)弊决,執(zhí)行a._proto_=B.prototype;的過程噪舀,于是當(dāng)在a上面訪問某個(gè)方法時(shí),如果a本身沒有這個(gè)方法飘诗,就會去找a._proto_与倡,由于它指向了B.prototype,然后就在B.prototype上面找了昆稿,然后由于任何對像都自帶_proto_屬性的纺座,如果在B.prototype身上還沒找到對應(yīng)方法,就會去找B.prototype._proto_溉潭,然后再找下一層(此時(shí)一般是之前就對B.prototype進(jìn)行了其他賦值净响,如B.prototype=C.prototype,或者B.prototype=D{}岛抄,又或者B.prototype=new C()這樣的操作别惦,才有下一步,否則就已經(jīng)到Object.prototype了)夫椭,一直找到Object.prototype掸掸,如果還是沒找到,就返回undefined蹭秋;
至于prototype屬性(這是一個(gè)對象)扰付,它只存在于函數(shù)(包括普通函數(shù)與構(gòu)建函數(shù))以及Object身上,其他類型的數(shù)據(jù)是沒有的仁讨,比如函數(shù)的實(shí)例化是沒有的:var p=new B();p.prototype為undefined;
(其實(shí)就是每個(gè)對像身上都有一個(gè)用于實(shí)現(xiàn)繼承的屬性羽莺,在函數(shù)身上是prototype,在其他數(shù)據(jù)身上是_proto_洞豁,有prototype的不會同時(shí)出現(xiàn)_proto_盐固,反之亦然)