原型链继承:(寄生组合式继承) 在ES6的class语法推出之前,要实现类的继承要通过修改原型链来实现。
核心: 子类的构造函数通过People.call(this)(Object.call(this))继承父类的属性,改变子类的原型为new People() (new Object())来继承父类的函数。
寄生组合式继承: 通过 Object.create() 将子类的原型继承到父类的原型上,它的高效率体现只调用了一次父类构造函数,并且因此避免了在父类的prototype 上面创建不必要的、多余的属性。同时,原型链还能保持不变,可以正常使用 instanceof 和 isPrototypeOf 。
//ES5原型链构造对象
//定义一个父类,本质上是定义父类的构造函数,其对应的People.prototype会自动被创建
function People(name, age) {
this.name = name || 'pray'
this.age = age || 27
}
//父类方法
People.prototype.sayHi = function () {
console.log(this.name + ' of ' + this.age + ' sayHi') //pray of 27 sayHi
}
//ES5原型链继承对象
//定义一个子类,通过在子类中用call函数,以子类的身份调用父类的构造函数,实现继承父类的成员变量
function Student(name, age) {
//继承父类属性
People.call(this, name, age)
}
//继承父类方法: 通过将Student的prototype的原型链__proto__指向People的prototype
Student.prototype = Object.create(People.prototype);
//处理构造函数指向问题构造函数指向问题
Student.prototype.constructor = Student;
let studentObj = new Student(); //这里传入参数就可以改变sayHi的输出
studentObj.sayHi()
class继承
核心: 使用extends表明继承哪个父类,并且在子类构造函数中必须调用super继承父类属性和方法。
// ES6 Class构造对象
class People {
constructor(name = 'pray', age = 18) {
this.name = name;
this.age = age;
}
sayHi() {
console.log(this.name + ' of ' + this.age + ' says Hi!') // student1 of 22 says Hi!
}
}
//ES6 extends 继承父类
class Student extends People {
constructor(name = 'student1', age = '22', score = 90) {
//继承父类属性
super(name, age);
//自身属性
this.score = score;
}
sayHi() {
//继承父类属性方法
super.sayHi()
//自身方法
console.log('score:' + this.score) // score:90
}
}
let person = new Student()
person.sayHi()