# 构造函数继承
- 缺点:只能继承构造器属性,不能继承原型链方法
function Father(name, age) {
this.name = name
this.age = age
}
Father.prototype.sayAge = function() {
return `hi,${this.age}`
}
function Son(name, age, school) {
Father.call(this, name, age)
this.school = school
}
let father = new Father('jamF', 40)
let son = new Son('jam', 15, 'whu')
console.log(son)
son.sayAge() // 报错
# 原型链继承
- 简单容易实现
- 如果要现在子类实例的原型对象方法,必须要在new后面操作
- 创建子类实例时候不能向父类构造函数中传参数
- 无法实现多继承
function Father(name, obj) {
this.name = name
this.obj = obj
}
Father.prototype.sayName = function() {
return this.name
}
function Son(name, obj, school) {
this.name = name
this.obj = obj
this.school = school
}
// 子类原型对象指向父类实例,因为父类可能也有父类,
// 用原型的话,无法访问到祖父类的原型对象
Son.prototype = new Father()
Son.prototype.constructor = Son
// 新增原型对象方法必须要在new操作后
Son.prototype.saySchool = function() {
return this.school
}
# 组合继承
- 使用原型链实现对原型方法的继承,使用构造函数实现对实例属性的继承
- 缺点会调用两次超类型的构造函数
function Father(name, age) {
this.name = name
this.age = age
}
Father.prototype.cars = ['benz', 'bwm']
Father.prototype.sayCars = function() {
return this.cars
}
function Son(name, age, school) {
Father.call(this, ...arguments)
this.school = school
}
// 创建原型链, 此时还是需要用Father类的原型对象
Son.prototype = new Father()
Son.prototype.constructor = Son
// 优化方案
// Son.prototype.__proto = Father.prototype
// => Son.prototype = Object.create(Father.prototype)
# ES6继承
- ES5的继承都是在子类中创建自己的this指向,最后将方法添加到this中
- ES6的继承是使用关键字先创建父类的实例对象this,最后在子类class中修改this
class Father {
x = 1
constructor(name, age) {
this.name = name
this.age = age
this.x = 2
}
static weight = '200KG'
sayHello(){
return `hello,i am ${this.name}`
}
static getWeight(){
return this.weight
}
getAge(){
return this.age
}
}
Father.prototype.sayName = function(){
return this.name
}
class Son extends Father {
constructor(name, age, school) {
super(name, age);
this.school = school
}
static weight = '50KG'
normalMethodTest() {
// 这里的super对象指向父类原型对象
// super.y = Father.prototype.y
// ES6规定,此处相当于 super.getAge.call(this)
return super.getAge()
}
static saticMethodTest(){
// 静态方法内的super指向父类,且调用的静态方法内的this指向子类
return super.getWeight()
}
}
# 实例继承
- 不限制调用方式,简单易实现
- 不能多次继承
function Father(name, age) {
this.name = name
this.age = age
}
Father.prototype.sayName = function() {
return this.name
}
function Son(name, age, school) {
let instance = new Father()
instance.name = name
instance.age = age
instance.school = school
return instance
}
← 递归的三种方式 js内方法执行时参数问题 →