原型链的继承

核心就是原型对象+构造函数组合使用

  1. function Person(name, age) {
  2. this.name = name;
  3. this.age = age;
  4. }
  5. Person.prototype.say = function() {
  6. return '我叫' + this.name + ',今年' + this.age + '岁。';
  7. };
  8. function Student(name, age, grade) {
  9. Person.call(null, name, age);
  10. this.grade = grade;
  11. }
  12. Student.prototype = Object.create(Person.prototype); //创建一个新对象
  13. Student.prototype.constructor = Student;
  14. //函数创建的对象.__proto__ === 该函数.prototype,该函数.prototype.constructor===该函数本身
  15. Student.prototype.exam = function() {
  16. console.log('正在考试!');
  17. };
  18. Student.prototype.say = function() {
  19. return Person.prototype.say.call(this) + this.grade + '学生。';
  20. };

1、首先在子构造函数中用call方法调用父构造函数,修改this指向,实现继承父类的实例属性
2、修改子构造函数的prototype的指向,把子类的原型链挂到父构造函数的原型对象上,从而实现子类继承父类的实例方法(需要给子类新增实例方法,挂到子构造函数的prototype上)
3、

class的继承

(使用extends实现继承)

  1. class Person {
  2. constructor(name, age) {
  3. this.name = name;
  4. this.age = age;
  5. }
  6. say() {
  7. return `我叫${this.name},今年${this.age}岁。`;
  8. }
  9. }
  10. class Student extends Person {
  11. constructor (name, age, grade) {
  12. super(name, age);
  13. this.grade = grade;
  14. }
  15. say() {
  16. return `${super.say()}${this.grade}学生`;
  17. }
  18. exam() {
  19. console.log('正在考试!');
  20. }
  21. }
  22. let stu = new Student('张三', 18, '高三');
  23. console.log(stu.say());
  24. // "我叫张三,今年18岁。高三学生"
  25. stu.exam();
  26. //正在考试!

注:子类的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)。