文章の目录
- 一、借助父构造函数继承属性
- 1、实现方式
- 2、优点
- 3、缺点
- 二、原型链继承
- 1、实现方式
- 2、优点
- 3、缺点
- 三、组合继承
- 四、ES6继承的实现方式
- 参考
- 写在最后
一、借助父构造函数继承属性
1、实现方式
- 先定义一个父构造函数(this指向为window);
- 再定义一个子构造函数(this指向为new出的实例化对象);
- 子构造函数通过call()、apply()、bind()等方式改变父的this指向继承父构造函数属性;
function Person(name) {
this.name = name;
this.song = function () {
console.log("唱歌");
};
}
Person.prototype.phone = function () {
console.log("打电话"); // 继承不了
};
function Son(name) {
Person.call(this, name); // apply bind
}
let zhangsan = new Son("张三");
console.log(zhangsan);
console.log(zhangsan.phone());
2、优点
避免了原型链继承的两个缺点,可以向父类传参,且不会造成原型属性共享的问题(因为父类构造函数中的属性继承到子类构造函数中,而非原型对象中)。
3、缺点
不能继承原型属性,无法实现函数复用,所有方法都只能放在构造函数中。
二、原型链继承
原型链是针对原型对象的,在查找实例属性时,先在实例中查找,如果没有找到,再到obj.__proto__
(=f1.prototype)原型对象,再到f1.prototype.__proto__
(=f2.prototype
),依次向上查找。
1、实现方式
将Person实例化给Son的原型对象,再实例化Son赋值给变量son,打印结果可见son通过prototype指向Father函数,Father函数通过prototype指向Object对象,让Son来继承其中的属性。
function Person(name) {
this.name = name;
this.song = function () {
console.log("唱歌");
};
}
Person.prototype.phone = function () {
console.log("打电话"); // 继承不了
};
function Son(name) {}
Son.prototype = new Person();
let zhangsan = new Son("张三");
console.log(zhangsan);
console.log(zhangsan.phone());
2、优点
能够继承构造函数属性,也能够继承原型属性。
3、缺点
- 首先属性值为引用类型值的原型属性被修改后可能会影响到所有的实例,并在此继承方式中,构造函数中的属性会继承到子类型,成为子类的原型对象的属性,这也是要在构造函数中定义属性,在原型中定义公共方法的原因。
- 在创建子类的实例时,不能向父类的构造函数中传递参数。
三、组合继承
组合继承(combination inheritance),也叫做伪经典继承,指的是将原型链和借用父构造函数组合到一块,其思路是用原型链实现对原型属性和方法的继承,而通过借用构造函数来实现对实例属性的继承。这样,既通过在原型上定义方法实现了函数复用,又能够保证每个实例都有它自己的属性。
function Person(name) {
this.name = name;
this.song = function () {
console.log("唱歌");
};
}
Person.prototype.phone = function () {
console.log("打电话"); // 继承不了
};
function Son(name) {
this.price = "price";
this.setScore = function () {};
}
Son.prototype = new Person();
Son.prototype.constructor = Son;
let zhangsan = new Son("张三");
console.log(zhangsan);
console.log(zhangsan.phone());
四、ES6继承的实现方式
通过关键字extends和super来实现
super特点
- super只能在子类中使用,可以在constructor 及 函数或静态方法中使用
- 不能单独使用super
- super调用类似函数调用可以根据父类构造函数传参数
- 如果子类中没有constructor,子类会自动调取super()且传入参数到父类
- 子类中需要在调取super之后调用this
class Person {
static height = "178cm";
constructor(name) {
this.name = name;
}
fn() {
console.log("父类的fn");
}
}
class Son extends Person {
constructor(name) {
super(name);
this.age = 20;
}
fn() {
// console.log(super);
super.fn();
console.log("子类fn");
}
}
console.log(Son.height);
let zhangsan = new Son("张三");
console.log(zhangsan);
zhangsan.fn();
参考
- 总结JS继承的六种方式
写在最后
如果你感觉文章不咋地
//(ㄒoㄒ)//
,就在评论处留言,作者继续改进;o_O???
如果你觉得该文章有一点点用处,可以给作者点个赞;\\*^o^*//
如果你想要和作者一起进步,可以微信扫描二维码,关注前端老L;~~~///(^v^)\\\~~~
谢谢各位读者们啦(^_^)∠※
!!!