#继承的其他形式之类式继承
![](https://box.kancloud.cn/f8130f43d77df9461ac4014b72221be6_857x391.png)
类: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)也能弹出小明。不过这种写法还有很多问题
![](https://box.kancloud.cn/8db8bd3513e1df6690ee35b519b9275f_1437x808.png)
问题一: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
```
解决方法:属性和方法继承的时候要分开继承
![](https://box.kancloud.cn/b74394ccc92c550d9fff5cb5e048d8da_1438x807.png)
```
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的选项卡组件开发