JavaScript进阶之路:继承

1. 什么是继承

想到继承,我会想到父子、子承父业之类的词,就是孩子得到父母的所有财产(一般情况下)。

如果从程序的角度解释,那首先说一下 Class 这个关键字,在一些其他的预言中像:Java、C# 等通过类(Class)实现继承(对于这块我多少还是了解的,因为大学学的是Java),这是一种面向对象的思想。然而 JS 中没有类,但是我们可以使用 Js 来模拟面向对象的编程思想通过构造函数模拟类的概念。

2. 通过原型实现继承

// 这里我叫做公共父类
function Person (name, age, sex) {
    this.name = name;
    this.age = age;
    this.sex = sex;
}
// 这里我叫做子类,去继承Person
Person.prototype.sayHi = function () {
    console.log('你好呀!朋友')
}
function Student (score) {
    this.score = score;
}
Student.prototype = new Person('ayong', 23, '男');
Student.prototype.totalScore = function () {
    console.log(`这学期考试我得了:${ this.score }`);
}

const stu = new Student(100);
console.log(stu.name); // ayong
console.log(stu.age);  // 23
console.log(stu.sex);  // 男
stu.sayHi();  // 你好呀!朋友
stu.totalScore();  // 这学期考试我得了:100分

⭐存在的不足:

  • Student 的原型每次指向 Person 时,需要初始化。
  • 当再次改变时,又需要初始化,始第一次初始化没有意义。

3. 借用构造函数实现继承

这里我们使用到了 call 方法指向 Person 的构造函数。

// 这里我叫做公共父类
function Person (name, age, sex) {
  this.name = name;
  this.age = age;
  this.sex = sex;
}
// 这里我叫做子类,去继承Person
Person.prototype.sayHi = function () {
  console.log('你好呀!朋友')
}
function Student (name, age, sex, score) {
  // 使用 call 方法
  Person.call(this, name, age, sex);
  this.score = score;
}

Student.prototype.totalScore = function () {
  console.log(`这学期考试我得了:${ this.score }`);
}

const stu = new Student('ayong',23, '男', 100);
console.log(stu.name);  // ayong
console.log(stu.age);  // 23
console.log(stu.sex);  // 男
stu.totalScore();  // 这学期考试我得了:100分
// 这行代码报错了
stu.sayHi();  // Uncaught TypeError: stu.sayHi is not a function

⭐存在的不足:

  • 清楚的看到,虽然我们可以正确的初始化对象,但是我们不能访问父类的方法。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ox9IUF91-1633764605122)(C:\Users\H7113821\Desktop\學習篇\筆記\js继承\js_constructor.PNG)]

4. 原型链和构造函数组合使用(推荐)

// 这里我叫做公共父类
function Person (name, age, sex) {
  this.name = name;
  this.age = age;
  this.sex = sex;
}
// 这里我叫做子类,去继承Person
Person.prototype.sayHi = function () {
  console.log('你好呀!朋友')
}
function Student (name, age, sex, score) {
  Person.call(this, name, age, sex);
  this.score = score;
}
// 不用进行传参
Student.prototype = new Person(); 

Student.prototype.totalScore = function () {
  console.log(`这学期考试我得了:${ this.score }`);
}

const stu = new Student('ayong',23, '男', 100);
console.log(stu.name);  // ayong
console.log(stu.age);  // 23
console.log(stu.sex);  // 男
stu.totalScore();  // 这学期考试我得了:100分
stu.sayHi();  // 你好呀!朋友

5. 通过拷贝实现继承

// 这里我叫做公共父类
function Person (name, age, sex) {
  this.name = name;
  this.age = age;
  this.sex = sex;
}
// 这里我叫做子类,去继承Person
Person.prototype.sayHi = function () {
  console.log('你好呀!朋友')
}
function Student (name, age, sex, score) {
  Person.call(this, name, age, sex);
  this.score = score;
}
// 应为 prototype 也是一个对象,所以我们深拷贝一下
for (const key in Person.prototype) {
  if (Person.prototype.hasOwnProperty(key)) {
    Student.prototype[key] = Person.prototype[key];
  }
}

Student.prototype.totalScore = function () {
  console.log(`这学期考试我得了:${ this.score }`);
}

const stu = new Student('ayong',23, '男', 100);
console.log(stu.name);
console.log(stu.age);
console.log(stu.sex);
stu.totalScore();
stu.sayHi();

☀️如果对于深浅拷贝不太熟悉的话:参考之前的博客js必会技能:深浅拷贝

6. ES6 中 Class 实现继承

类似于 Java 中的 Class ,使用 extends 关键字继承父类,基本使用差不多,但是终归还是一个函数,不像 Java 中类的概念。

// 这是一个公共的父类
class Person {
  // 构造函数
  constructor(name, age, sex){
    this.name = name;
    this.age = age;
    this.sex = sex;
  }
  // Person 类中的方法
  sayHi () {
    console.log('你好呀!朋友')
  }
}
// 子类,通过 extends 继承 Person 类
class Student extends Person {
  constructor(name, age, sex, score){
    // 写在 constructor 中的第一句。
    super(name, age, sex);
    this.score = score;
  }
  // Student 类中的方法
  totalScore () {
    console.log(`这学期考试我得了:${ this.score }`);
  }
}

const stu = new Student('ayong',23, '男', 100);  
console.log(stu.name);  // ayong 
console.log(stu.age);  // 23
console.log(stu.sex);  // 男
stu.totalScore();  // 这学期考试我得了:100分
stu.sayHi();  // 你好呀!朋友

总结

在学习继承之前,我认为了解原型链还是有必要的。因为我们能够很清楚的知道每个类之间的关系(这里我就统称为类了)。可能是之前接触过 Java 的原因让我对继承似乎不那么的陌生,ES6 出了 Class 之后,就感觉是在写 Java 一样,像我在学习 TS 的时候接触到的 implements、interface,都让我感到很亲切。
最后祝大家前程似锦。🎉🎉🎉

posted @ 2021-10-09 15:35  ayong6  阅读(32)  评论(0)    收藏  举报