原型链的继承
核心就是原型对象+构造函数组合使用
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.say = function() {
return '我叫' + this.name + ',今年' + this.age + '岁。';
};
function Student(name, age, grade) {
Person.call(null, name, age);
this.grade = grade;
}
Student.prototype = Object.create(Person.prototype); //创建一个新对象
Student.prototype.constructor = Student;
//函数创建的对象.__proto__ === 该函数.prototype,该函数.prototype.constructor===该函数本身
Student.prototype.exam = function() {
console.log('正在考试!');
};
Student.prototype.say = function() {
return Person.prototype.say.call(this) + this.grade + '学生。';
};
1、首先在子构造函数中用call方法调用父构造函数,修改this指向,实现继承父类的实例属性
2、修改子构造函数的prototype的指向,把子类的原型链挂到父构造函数的原型对象上,从而实现子类继承父类的实例方法(需要给子类新增实例方法,挂到子构造函数的prototype上)
3、
class的继承
(使用extends实现继承)
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
say() {
return `我叫${this.name},今年${this.age}岁。`;
}
}
class Student extends Person {
constructor (name, age, grade) {
super(name, age);
this.grade = grade;
}
say() {
return `${super.say()}${this.grade}学生`;
}
exam() {
console.log('正在考试!');
}
}
let stu = new Student('张三', 18, '高三');
console.log(stu.say());
// "我叫张三,今年18岁。高三学生"
stu.exam();
//正在考试!
注:子类的constructor中,必须调用super方法,否则新建实例时会报错
constructor中,super被当做函数看待,super(name, age)代表调用父类的构造函数,相当于Person.call(this, name, age),另外super( )只能用于constructor中;say方法中的super.say()是将super当对象看待,它指向父类的原型对象Person.prototype.super.say()相当于Person.protoype.say.call(this)。