JS如何使用class实现继承

1,137 阅读3分钟

【前言】在class出现之前,JavaScript 实现继承是件麻烦事,构造函数继承有加上原型上的函数不能复用的问题;原型链继承又存在引用值属性的修改不独立的问题;组合继承又存在两次调用构造函数的问题,寄生组合继承,写起来又太麻烦了,总之,在class类问世前JavaScipt 实现继承真是件麻烦事儿。但从ES6开始,新的关键字class被引入到Javascript中,它的出现就是让定义类更加简单。

原生JS实现


function Student(name) {
    this.name = name;
}
// 现在要给这个Student新增一个方法
Student.prototype.hello = function () {
    console.log('Hello, ' + this.name + '!');    //Hello,小明!
}
Student.prototype.hello.apply(new Student("小明"));

使用es6的class实现

class Student{
 constructor(name, score) {
         this.name = name;
   }
   hello(){
   console.log('Hello, ' + this.name + '!'); 
   }
}
const xiaoMing = new Student('小明')
xiaoMing.hello()     //Hello,小明!

比较两种写法,class的定义的Student对象中就包含了constructor和已经定义在原型对象身上的hello方法,这种写法使得代码更加简洁,而使用class的写法还有一个好处就是可以更加简单的实现继承属性和方法,可直接通过extends关键值字实现。

使用class实现继承

定义一个StudentTeacher类,实现属性和方法的继承

//定义一个老师类
class Teacher {
    constructor(name, subject) {
        this.name = name;
        this.subject = subject;
    }
}
//定义一个学生类
class Student {
    constructor(name, score) {
        this.name = name;
        this.score = score;
    }
}
const student = new Student('张三',100);
const teacher = new Teacher('曹老师','web前端')
console.log(student);
console.log(teacher);

输出结果:

image.png

从输出结果观察,无论是Student还是Teacher构造函数,他们的prototype访问原型对象上存在一个study的方法和相同的name属性,类似这种情况就可以考虑使用方法的继承,定义一个公共的方法。

class Person {
    constructor(name) {
        this.name = name;
    }
    //公共的方法
    study(){
        console.log('我是公共的方法')
    }

}

//定义一个老师对象
class Teacher extends Person {
    constructor(name, subject) {
        super(name)    //继承公共的属性
        this.subject = subject;
    }
}

//定义一个学生对象
class Student extends Person {
    constructor(name, score) {
        super(name)    //继承公共的属性
        this.score = score;
    }
}
const student = new Student('张三', 100);
const teacher = new Teacher('曹老师', 'web前端')
student.study()
teacher.study()
console.log(student);
console.log(teacher);

输出结果:

image.png

new操作符的作用

通过以上代码实现,new操作符主要实现了以下功能:

  • new 通过构造函数 Student 创建出来的实例可以访问到构造函数中的属性。
  • new 通过构造函数 Student 创建出来的实例可以访问到构造函数原型链中的属性(即实例与构造函数通过原型链连接了起来)

总结看到new关键字主要做了以下的工作:

  1. 创建一个新的对象obj
  2. 将对象与构建函数通过原型链连接起来;
  3. 将构建函数中的this绑定到新建的对象obj上;
  4. 根据构建函数返回类型作判断,如果是原始值则被忽略,如果是返回对象,需要正常处理。

【结语】通过阅读这篇文章相信你对ES6的class继承有了更加深刻的认识,后续将会继续更新前端开发技术栈相关内容,欢迎👍。