js繼承的實現(xiàn)方式
先理解一下prototype和__proto__;
????????我們創(chuàng)建的每一個函數(shù)都有一個prototype屬性(原型),這個屬性是一個對象呵俏,它的用途是包含可以由特定類型的所有實例共享的屬性和方法。(這個對象下面有個屬性,設(shè)個屬性是另一個對象的應(yīng)用违诗,這個屬性就是一個對象。)
????????function是對象疮蹦,function的原型prototype也是對象诸迟,它們都會具有對象共有的特點。即:對象具有屬性__proto__愕乎,每個對象都會在其內(nèi)部初始化一個屬性阵苇,就是__proto__,當(dāng)我們訪問一個對象的屬性時,如果這個對象的內(nèi)部不存在這個屬性感论,那么它就會去__proto__里找這個屬性绅项,這個__proto__又會有自己的__proto__,于是就這樣一直找下去,也就是我們平時所說的原型鏈概念比肄。__proto__可稱之為隱式原型快耿,一個對象的隱式原型指向構(gòu)造該對象的構(gòu)造函數(shù)的原型,這也保證了實例能夠訪問在構(gòu)造函數(shù)原型中定義的屬性和方法芳绩。
????????function這個特殊的對象掀亥,除了和其它對象一樣有上述__proto__屬性之外,還有自己特有的屬性————原型屬性(prototype)示括,這個屬性是一個指針铺浇,指向一個對象,這個對象的用途就是包含所有實例共享的屬性和方法(我們把這個屬性叫做原型對象)垛膝。prototype是通過調(diào)用構(gòu)造函數(shù)而創(chuàng)建的那個實例的原型對象鳍侣。使用原型對象的好處是可以讓所有對象實例共享他所包含的屬性和方法,不必在構(gòu)造函數(shù)中定義對象實例的信息吼拥,而是可以將這些信息直接添加到原型對象中倚聚。原型對象也有一個屬性,叫做constructor凿可,這個屬性包含了一個指針惑折,指回原構(gòu)造函數(shù)授账。
? ? ? ? prototype和__proto__聯(lián)系
? prototype和__proto__都指向原型對象,任意一個函數(shù)(包括構(gòu)造函數(shù))都有一個prototype屬性惨驶,指向該函數(shù)的原型對象白热,同樣任意一個構(gòu)造函數(shù)實例化的對象,都有一個__proto__屬性(__proto__并非標(biāo)準(zhǔn)屬性粗卜,ECMA-262第5版將該屬性或指針稱為[[Prototype]]屋确,可通過Object.getPrototypeOf()標(biāo)準(zhǔn)方法訪問該屬性)指向構(gòu)造函數(shù)的原型對象。
實例的__proto__與構(gòu)造函數(shù)的prototype相同续扔。
Function的__proto__指向函數(shù)本身攻臀。
Function的prototype指向函數(shù)本身。
Object的__proto__指向原型對象纱昧。
prototype和__proto__區(qū)別
先定義一個父類刨啸。
1.原型鏈繼承。
核心:將父類的實例作為子類的原型识脆。
特點:
? ? ? ? 1.非常純粹的繼承關(guān)系设联,實例是子類的實例,也是父類的實例
? ? ? ? 2.父類新增原型方法/原型屬性存璃,子類都能訪問到仑荐。
? ? ? ? 3.簡單,易于實現(xiàn)纵东。
缺點:
? ? ? ? 1.想要為子類新增屬性和方法粘招,必須要在new Animal()這樣的語句之后執(zhí)行,不能放到構(gòu)造器中偎球。
? ? ? ? 2.無法實現(xiàn)多繼承洒扎。
? ? ? ? 3.來自原型對象的所有屬性被所有實例共享。
? ? ? ? 4.創(chuàng)建子類實例時衰絮,無法向父類構(gòu)造函數(shù)傳參袍冷。
2.構(gòu)造繼承
核心:使用父類的構(gòu)造函數(shù)來增強子類實例,等于是復(fù)制父類的實例屬性給子類猫牡。
特點:
? ? ? ? 1.解決了1中胡诗,子類實例共享父類引用屬性的問題。
? ? ? ? 2.創(chuàng)建子類實例時淌友,可以向父類傳遞參數(shù)煌恢。
? ? ? ? 3.可以實現(xiàn)多繼承(call多個父類對象)。
缺點:
? ? ? ? 1.實例并不是父類的實例震庭,只是子類的實例瑰抵。
? ? ? ? 2.只能繼承父類的實例屬性和方法,不能繼承原型屬性和方法器联。
? ? ? ? 3.無法實現(xiàn)函數(shù)復(fù)用二汛,每個子類都有父類實例函數(shù)的副本婿崭,影響性能。
3.實例繼承
特點:
? ? ? ? ? ?1.不限制調(diào)用方式肴颊,不管是new 子類()還是子類(),返回的對象具有相同的效果
缺點:
? ? ? ? ? ?1.實例是父類的實例氓栈,不是子類的實例
? ? ? ? ? ?2.不支持多繼承
4.拷貝繼承
特點:
? ? ? ? 1.支持多繼承
缺點:
? ? ? ? 1.效率較低,內(nèi)存占用高(因為要拷貝父類的屬性)
? ? ? ? 2.無法獲取父類不可枚舉的方法(不可枚舉方法婿着,不能使用for in 訪問到)
5.組合繼承
特點:
? ? ? ? 1.彌補了方式2的缺陷颤绕,可以繼承實例屬性/方法,也可以繼承原型屬性/方法
? ? ? ? 2.既是子類的實例祟身,也是父類的實例
? ? ? ? 3.不存在引用屬性共享問題
? ? ? ? 4.可傳參
? ? ? ? 5.函數(shù)可復(fù)用
缺點:
????????1.調(diào)用了兩次父類構(gòu)造函數(shù),生成了兩份實例(子類實例將子類原型上的那份屏蔽了)
6物独、寄生組合繼承
總結(jié):