#繼承的其他形式之類式繼承

類:JS是沒有類的概念的,在JS中可以把構造函數看做是類
```
function Aaa(){ // 父類
this.name = '小明';
}
Aaa.prototype.showName = function(){
alert(this.name);
};
function Bbb(){ // 子類
}
Bbb.prototype = new Aaa(); // 這一句話就是類式繼承
var b1 = new Bbb();
b1.showName(); // 小明
alert(b1.name); // 小明
```
b1調用showName方法的過程:它會先從b1開始找,由于b1本身并沒有showName方法,因此它會通過原型鏈找到Bbb.prototype繼而找到a1,a1下面也沒有showName方法,于是a1又會通過原型鏈找到Aaa.prototype就能找到showName方法了。同理:alert(b1.name)也能彈出小明。不過這種寫法還有很多問題

問題一:constructor指向問題
```
function Aaa(){ // 父類
this.name = '小明';
}
Aaa.prototype.showName = function(){
alert(this.name);
};
function Bbb(){ // 子類
}
Bbb.prototype = new Aaa(); // 這一句話就是類式繼承
var b1 = new Bbb();
alert(b1.constructor);
```
打印出來的結果是
```
function Aaa(){ // 父類
this.name = '小明';
}
```
這就說明Bbb的constructor指向被修改了,解決如下:
```
function Aaa(){ // 父類
this.name = '小明';
}
Aaa.prototype.showName = function(){
alert(this.name);
};
function Bbb(){ // 子類
}
Bbb.prototype = new Aaa(); // 這一句話就是類式繼承
Bbb.prototype.constructor = Bbb; // 修正 constructor 指向
var b1 = new Bbb();
alert(b1.constructor);
```
問題二:多個對象之間屬性會相互影響
```
function Aaa() { // 父類
this.name = [1, 2, 3];
}
Aaa.prototype.showName = function () {
alert(this.name);
};
function Bbb() { // 子類
}
Bbb.prototype = new Aaa(); // 這一句話就是類式繼承
Bbb.prototype.constructor = Bbb; // 修正 constructor 指向
var b1 = new Bbb();
b1.name.push(4);
var b2 = new Bbb();
alert(b2.name); // 1,2,3,4
```
解決方法:屬性和方法繼承的時候要分開繼承

```
function Aaa() { // 父類
this.name = [1, 2, 3];
}
Aaa.prototype.showName = function () {
alert(this.name);
};
function Bbb() { // 子類
}
// 繼承方法
var F = function(){};
F.prototype = Aaa.prototype;
Bbb.prototype = new F(); // 這一句話就是類式繼承
Bbb.prototype.constructor = Bbb; // 修正 constructor 指向
var b1 = new Bbb();
var b2 = new Bbb();
alert(b2.name); // undefined
```
通過上面可以看出通過b2去找name屬性是找不到的,因為只繼承了方法,最終解決方法如下:
```
function Aaa() { // 父類
this.name = [1, 2, 3];
}
Aaa.prototype.showName = function () {
alert(this.name);
};
function Bbb() { // 子類
// 繼承屬性
Aaa.call(this);
}
// 繼承方法
var F = function(){};
F.prototype = Aaa.prototype;
Bbb.prototype = new F(); // 這一句話就是類式繼承
Bbb.prototype.constructor = Bbb; // 修正 constructor 指向
var b1 = new Bbb();
b1.name.push(4);
var b2 = new Bbb();
alert(b2.name); // 1,2,3
```
- 01 JS面向對象及組件開發
- 02 傳統的過程式編寫選項卡
- 03 用面向對象封裝通用選項卡
- 04 控制多個選項卡自動播放
- 05 用面向對象編寫拖拽
- 06 JS面向對象及組件開發
- 07 hasOwnProperty和constructor的使用
- 08 instanceof運算符的使用
- 09 利用toString做類型判斷
- 10 什么是面向對象的繼承
- 11 面向對象之拷貝繼承
- 12 編寫繼承的拖拽
- 13 繼承的其他形式之類式繼承
- 14 繼承的其他形式之原型繼承
- 15 組件開發是什么
- 16 給拖拽組件配置不同參數
- 17 封裝彈框組件
- 18 使用對象標記已彈出彈框
- 19 復雜組件開發之自定義事件
- 20 原生JS實現自定義事件
- 21 自定義事件實例
- 22 基于JQ的選項卡組件開發