欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

ES6中的类

程序员文章站 2022-07-16 21:53:54
...

1. ES5中的仿类

ES5中没有类,与类最相近的是创造一个构造器,然后将方法绑定到构造器的原型上,例子如下:

  function Person (name) {
      this.name = name
    }
    Person.prototype.getName = function () {
      return this.name
    }
    Person.prototype.setName = function (value) {
      this.name = value
    }

    let person = new Person('zhou') // 创建一个实例
    console.log(person.getName()) // zhou
    person.setName('jiang')
    console.log(person.getName()) // jiang
    console.log(person instanceof Person) // true

2. ES6中的类

class Person {
      constructor(name) {
        this.name = name
      }
      getName () {
        return this.name
      }
      setName(value){
        this.name = value
      }
    }
    let person = new Person('zhou')
    console.log(person.getName()) // zhou
    person.setName('jiang')
    console.log(person.getName()) // jiang

constructor 里面放自有属性,类本质是一个函数

console.log(person instanceof Person) // true
    console.log(typeof person) // object 
    console.log(person instanceof Object) // true
    console.log(typeof Person) // function

3. 继承

class Person {
      constructor(name, age) {
        this.name = name
        this.age = age
      }
      getInfo () {
        return `my name is ${this.name}, my age is ${this.age}`
      }
      setName(name, age){
        this.name = name
        this.age = age
      }
    }
    // 定义Student集成Person
    class Student extends Person {
      constructor(name, age) {
        super(name, age) // 继承父类的变量 通过super给父类传递参数 name: zhou,age:15
      }
    }

    let student1 = new Student('zhou', 15)
    console.log(student1 instanceof Student) // true
    console.log(student1 instanceof Person) // true
    console.log(student1.getInfo()) // my name is zhou, my age is 15

 

使用 super() 时需牢记以下几点:
1. 只能在派生类中使用 super() 。若尝试在非派生的类(即:没有使用 extends关键字的类)或函数中使用它,就会抛出错误。
2. 构造器中,你必须在访问 this 之前调用 super() 。由于 super() 负责初始化this ,因此试图先访问 this 自然就会造成错误。

 4. 屏蔽派生类中的方法

派生类中的方法总是会屏蔽基类的同名方法,覆盖的意思

class Person {
      constructor(name, age) {
        this.name = name
        this.age = age
      }
      getInfo () {
        return `my name is ${this.name}, my age is ${this.age}`
      }
      setName(name, age){
        this.name = name
        this.age = age
      }
    }
    // 定义Student集成Person 派生类
    class Student extends Person {
      constructor(name, age) {
        super(name, age) // 继承父类的变量 通过super给父类传递参数 name: zhou,age:15
      }
      // 屏蔽父类中的方法
      getInfo() {
        return this.name
      }
    }

    let student1 = new Student('zhou', 15)
    console.log(student1.getInfo()) // zhou
    

5. 在构造函数中使用 new.target

在简单情况下,new.target 就等于本类的构造器函数

let student = new Student() 

new.target 就是 Student 谁new了new.target 就只向谁

 class Person {
      constructor(name, age) {
        console.log(new.target === Person) // false
        this.name = name
        this.age = age
      }
      getInfo () {
        return `my name is ${this.name}, my age is ${this.age}`
      }
      setName(name, age){
        this.name = name
        this.age = age
      }
    }
    // 定义Student集成Person 派生类
    class Student extends Person {
      constructor(name, age) {
        console.log(new.target === Student) // true
        super(name, age)
      }
      // 屏蔽父类中的方法
      getInfo() {
        return this.name
      }
    }

    let student1 = new Student('zhou', 15)

可以使用 new.target 来创建一个抽象基类(一种不能被实例化的类)

class Person {
      constructor(name, age) {
      // 抛出错误
        if (new.target !== Person) {
          throw new Error('err')
        }
        this.name = name
        this.age = age
      }
      getInfo () {
        return `my name is ${this.name}, my age is ${this.age}`
      }
      setName(name, age){
        this.name = name
        this.age = age
      }
    }
    // 定义Student集成Person 派生类
    class Student extends Person {
      constructor(name, age) {
        super(name, age)
      }
      // 屏蔽父类中的方法
      getInfo() {
        return this.name
      }
    }

    let student1 = new Student('zhou', 15)