物件導向:類的定義和繼承的幾種方式
類的定義、例項化
類的定義/類的宣告
方式一: 用建構函式模擬類(傳統寫法)
function Animal1() {
this.name = 'smyhvae'; //通過this,表明這是一個建構函式
}
方式二: 用 class 宣告(ES6的寫法)
class Animal2 {
constructor() { //可以在建構函式裡寫屬性
this.name = name;
}
}
控制檯的效果:
例項化
類的例項化很簡單,直接 new 出來即可。
console.log(new Animal1(),new Animal2()); //例項化。如果括號裡沒有引數,則括號可以省略
繼承的幾種方式
繼承的本質就是原型鏈。
方式一: 藉助建構函式
function Parent1() {
this.name = 'parent1 的屬性';
}
function Child1() {
Parent1.call(this); //【重要】此處用 call 或 apply 都行:改變 this 的指向
this.type = 'child1 的屬性';
}
console.log(new Child1);
【重要】上方程式碼中,最重要的那行程式碼:在子類的建構函式裡寫了Parent1.call(this)
;,意思是:讓Parent
的建構函式在child
的建構函式中執行。發生的變化是:改變this
的指向,parent
的例項 --> 改為指向child
的例項。導致 parent
的例項的屬性掛在到了child
的例項上,這就實現了繼承。
列印結果:
上方結果表明:
child
先有了parent
例項的屬性(繼承得以實現),再有了child
例項的屬性。
分析:
這種方式,雖然改變了 this
的指向,但是,Child1
無法繼承 Parent1
的原型。也就是說,如果我給 Parent1
的原型增加一個方法:
Parent1.prototype.say = function () {
};
上面這個方法是無法被 Child1 繼承的。如下:
方法二: 通過原型鏈實現繼承
/*
通過原型鏈實現繼承
*/
function Parent() {
this.name = 'Parent 的屬性';
}
function Child() {
this.type = 'Child 的屬性';
}
Child.prototype = new Parent(); //【重要】
console.log(new Child());
列印結果:
【重要】上方程式碼中,最重要的那行:每個函式都有prototype
屬性,於是,建構函式也有這個屬性,這個屬性是一個物件。現在,我們把Parent的例項賦值給了Child的prototye,從而實現繼承。此時,Child
建構函式、Parent
的例項、Child
的例項構成一個三角關係。於是:
new Child.__proto__ === new Parent()
的結果為true
分析:
這種繼承方式,Child
可以繼承 Parent
的原型,但有個缺點:
缺點是:如果修改 child1
例項的name
屬性,child2
例項中的name
屬性也會跟著改變。
如下:
上面的程式碼中, child1
修改了arr
屬性,卻發現,child2
的arr
屬性也跟著改變了。這顯然不太好,在業務中,兩個子模組應該隔離才對。如果改了一個物件,另一個物件卻發生了改變,就不太好。
造成這種缺點的原因是:child1和child2共用原型。即:chi1d1.__proto__ === child2__proto__
是嚴格相同。而 arr
方法是在 Parent
的例項上(即 Child
例項的原型)的。
方式三: 組合的方式:建構函式 + 原型鏈
就是把上面的兩種方式組合起來:
/*
組合方式實現繼承:建構函式、原型鏈
*/
function Parent3() {
this.name = 'Parent 的屬性';
this.arr = [1, 2, 3];
}
function Child3() {
Parent3.call(this); //【重要1】執行 parent方法
this.type = 'Child 的屬性';
}
Child3.prototype = new Parent3(); //【重要2】第二次執行parent方法
var child = new Child3();
這種方式,能解決之前兩種方式的問題:既可以繼承父類原型的內容,也不會造成原型裡屬性的修改。
這種方式的缺點是:讓父親Parent
的構造方法執行了兩次。
ES6中的繼承方式,一帶而過即可,重點是要掌握ES5中的繼承。
相關文章
- 物件導向:繼承物件繼承
- 物件導向--繼承物件繼承
- 物件導向-繼承物件繼承
- JS的物件導向(理解物件,原型,原型鏈,繼承,類)JS物件原型繼承
- JavaScript的幾種繼承方式JavaScript繼承
- Golang物件導向_繼承Golang物件繼承
- java物件導向繼承Java物件繼承
- 物件導向之繼承物件繼承
- php物件導向--繼承PHP物件繼承
- 物件導向中類和物件的定義是什麼?物件
- JavaScript物件導向 ~ 原型和繼承(1)JavaScript物件原型繼承
- JavaScript物件導向—繼承的實現JavaScript物件繼承
- javascript的物件導向的繼承實現JavaScript物件繼承
- 物件導向之_繼承概念物件繼承
- Javascript物件導向與繼承JavaScript物件繼承
- js實現繼承的幾種方式JS繼承
- js實現繼承的幾種方式和對比JS繼承
- Javascript實現物件導向繼承JavaScript物件繼承
- 21. 物件導向之繼承物件繼承
- Javascript中的幾種繼承方式比較JavaScript繼承
- 物件導向(ES5與ES6類的繼承解析)物件繼承
- python中物件導向_類_物件的概念與定義Python物件
- javascript實現的繼承的幾種常用方式JavaScript繼承
- python物件導向的繼承-組合-02Python物件繼承
- javascript物件導向繼承的簡單例項JavaScript物件繼承單例
- JavaScript之物件導向的繼承淺析2JavaScript物件繼承
- 物件導向 -- 三大特性之繼承 補充 抽象類 介面類物件繼承抽象
- 物件導向 -- 三大特性之繼承物件繼承
- 說清楚javascript物件導向、原型、繼承JavaScript物件原型繼承
- 5-Java物件導向-繼承(下)Java物件繼承
- 《JavaScript物件導向精要》之五:繼承JavaScript物件繼承
- java學習——物件導向之繼承Java物件繼承
- php物件導向多繼承實現PHP物件繼承
- JavaScript物件導向那些東西-繼承JavaScript物件繼承
- Effective C++:物件導向與繼承C++物件繼承
- JAVA物件導向高階一:繼承Java物件繼承
- JS 總結之原型繼承的幾種方式JS原型繼承
- 實現繼承的幾種方式及工作原理繼承