JS 繼承的四種方式

2021-10-11 06:53:41 字數 3820 閱讀 7792

js 本身是基於物件導向開發的程式語言。類:封裝、繼承、多型

繼承機制使得不同的例項可以共享建構函式的原型物件的屬性和方法

以下情況都是 b 為子類,a 為父類

基本思想是利用原型讓乙個引用型別繼承另乙個引用型別的屬性和方法。我們知道每個建構函式都有乙個原型物件(prototype),原型物件都包含乙個指向建構函式的指標(constructor),而例項都包含乙個指向原型物件的內部指標(__proto__

那麼,如果讓乙個建構函式的原型物件等於另乙個型別的例項,此時的原型物件將包含乙個指向另乙個原型的指標,相應地,另乙個原型中也包含著乙個指向另乙個建構函式的指標

原型繼承:

父類中私有和公有的屬性方法,最後都變為子類例項公有的

和其它語言不同的是,原型鏈並不會把父類的屬性方法,"拷貝"給子類,而是讓子類例項基於__proto__原型鏈找到自己定義的屬性和方法(「指向/查詢」)

functiona(

)a.prototype.

geta

=function()

;functionb(

)b.prototype =

newa()

;// 讓 b 類的原型指向 a 類的例項

原型鏈繼承的問題:通過原型鏈繼承後,b 的原型繼承了 a 的例項屬性變成了 b 的原型屬性,若繼承 a 的例項屬性裡面有引用資料型別,更改 b 的例項屬性 colors,後續 b 的例項的例項屬性 colors 都會被修改(並不是拷貝,而是指向)

functiona(

)functionb(

)// new a()建立例項,例項擁有 colors 屬性

// b 的原型改為該例項,則 b 的原型中新增 colors 屬性

b.prototype =

newa()

;let arr1 =

newb()

;arr1.colors.

push

("yellow");

console.

log(arr1.colors)

;// [ 'red', 'green', 'yellow' ]

let arr2 =

newb()

;console.

log(arr2.colors)

;// [ 'red', 'green', 'yellow' ]

原型鏈繼承的另乙個問題:在建立子型別的例項時,不能向父型別的建構函式中傳遞引數。所以實踐中很少會單獨使用原型鏈繼承

應用:

functionfn(

));}

console.

log(fn(

5,3,

6,4)

);// array

call 繼承:

functiona(

)functionb(

)let b =

newb()

;

借用建構函式問題:因為方法都是在建構函式中定義,因此就沒有函式復用。而且,超型別的原型中定義的方法,對子型別來說是不可見的(只能新增私有屬性)。實踐中很少會單獨使用借用建構函式

基本思想:借用原型鏈實現對原型屬性和方法的繼承,通過借用建構函式來實現例項屬性的繼承。這樣既通過原型上定義方法實現了函式的復用,又保證每個例項都有自己的屬性

需求:b 類要繼承 a 類的私有屬性和公有屬性

functiona(

)a.prototype.

geta

=function()

;functionb(

)b.prototype.

getb

=function()

b

.prototype =

a.prototype;

b.prototype.

getb

=function()

;

解決方法:我們可以先用借用 call 繼承獲取 a 類的私有屬性

functionb(

)

再用原型鏈繼承獲取 a 類公有屬性(需要寫在b.prototype.getb

// 1.可以考慮用普通物件做中介軟體

let obj =

;obj.__proto__ =

a.prototype;

b.prototype = obj;

b.prototype.constructor =b;

// 2.可以考慮用函式做中介軟體

functionf(

)f.prototype =

a.prototype;

b.prototype =

newf()

;b.prototype.constructor =b;

// 3.使用object.create()方法

b.prototype = object.

create(a

.prototype);b

.prototype.constructor =b;

// 4.借用例項

b.prototype =

newa()

;b.prototype.constructor =

b;

functiona(

)a.prototype.

geta

=function()

;functionb(

)// 2.b.prototype.__proto__ = a.prototype

b.prototype = object.

create(a

.prototype);b

.prototype.constructor =b;

b.prototype.

getb

=function()

let b =

newb()

;

組合繼承融合了原型鏈和借用建構函式的優點,而且 instanceof 也能用於識別基於組合繼承建立的物件,所以實踐中最常用組合式繼承

注意:

es6 創造的就是類,不能當做普通函式執行,只能 new 執行

如果繼承寫 constructor 一定要寫 super

其實靜態屬性不比寫在 constructor 裡面,使用 static 宣告也可以

如果新增公有屬性,只能通過prototype上新增,不能直接寫在 class 裡面

class

a// a.prototype.getx=function(){}

getx()

}// 注意:繼承後一定要在constructor加上super

class

bextends

agety()

}let b =

newb

()

js繼承的四種實現方式

一 原型鏈繼承 核心 將父類的例項作為子類的原型。宣告乙個動物的類 function animal name animal.prototype.公 父類新增原型方法 原型屬性,子類都能訪問到 animal.prototype.age 3 animal.prototype.sleep function...

js繼承的四種方式,例項詳解

js 本身是基於物件導向開發的語言 封裝 繼承 多型 封裝 類也是乙個函式,把實現乙個 的功能進行封裝,以此實現 低耦合高內聚 多型 過載 重寫 重寫 子類重寫父類上的方法 過載 相同的方法,由於引數或者返回值不同,具備了不同的功能。js中的過載 同乙個方法內,根據傳參不同實現不同的功能 繼承 子類...

JavaScript四種繼承方式

原型繼承 function person name,age person.prototype.say function function man man.prototype new person 霍頓 22 這句是重點,敲黑板 var man1 new man man1.say var man2 n...