ES6中新增 class 关键字,用于定义类,进行面向对象开发,本质就是一个语法糖(原型链继承+借用构造函数继承)

定义/实例化

  1. class ClassName { }
  2. const instance = new ClassName('es6 class')
  • 使用 class 关键字声明一个类
  • 只能使用 new 关键字创建实例
  • ES6的类只是一个语法糖,本质还是ES5的构造函数(constructor)

实例成员

  1. class ClassName {
  2. prop1 = '' // 实例属性
  3. constructor () {
  4. this.prop2 = '' // 实例属性
  5. }
  6. method () {} // 实例方法
  7. }
  • 直接在类中书写即可,或者在方法中通过this添加
  • 实例属性:成员名 = 值 、在constructor中使用this添加,是在实例自身上
    • 成员名 = 值 方式本质就是 this 添加的语法糖
  • 实例方法:成员名 () {},类的实例方法都是定义在原型对象上,且都是不可枚举的

constructor方法

  1. class ClassName {
  2. type = ''
  3. constructor (type) {
  4. this.type = type
  5. }
  6. }
  • 该方法是类的默认方法,new对象时,会自动调用该方法
  • 如果没有定义constructor方法,那么会自动生成一个空的constructor方法,也是挂在原型上 ```javascript Class MyClass { constructor() {
    1. return Object.create(null)
    } }

new MyClass instanceof MyClass // false


- constructor方法默认返回实例(即this),但可以手动指定返回另外一个对象

<a name="tPGZE"></a>
## 取值函数(getter)/存值函数(setter)
在类的内部,可以使用 `get` 和 `set` 关键字,对某个属性设置存值函数和取值函数,拦截对该属性的操作
```javascript
class ClassName {
    _age = 18
  get name() {            // 取值器
    return '阿坤
  }
  set age( ) {            // 存值器
      this._age = 18
  }  get
    get age() {
      return this._age
  }
}
  • 函数的名称,就是那个被拦截的属性, 实例.存取器名称
    • get 关键字定义 getter,set 关键字定义 setter、
  • 可以通过存取器实现只读属性(只写getter)

属性表达式

const methodName = "myMethod"
const propName = "propName"
class MyClass {
  [myMethod] () {
      // ...
  }
    [propName] = "..."
}
  • 类的属性名,可以使用表达式,引用变量

Class表达式

const MyClass = class Me {
    // ...
}
  • 类似于函数表达式,使用一个变量进行引用,类名可以省略
  • 采用Class表达式,可以写出立即执行的Class
    const person = new Class {
      constructor(name) {
          this.name = name
    }
    }("张三")
    

静态成员

class ClassName {
  static prop = ''     // 静态属性
  static method () {}  // 静态方法
}
  • 通过 static 关键字声明静态成员,是属于类自身的方法
  • 静态成员会被子类继承,或者通过super获取静态成员 ```javascript class Father { static sayHi () {} }

class Son extends Father { static sayHi () { return super.sayHi() } }


<a name="zrvzI"></a>
# 继承
**通过 **`**extends**`** 关键字进行继承**
```javascript
class Son extends Father {
    constructor(...args) {
      super(...args)
  }
}

  • 子类的 prototype 会指向父类

super关键字

继承后,子类的方法内会有一个 super,既可以当作构造函数使用,也可以当作对象使用

作为函数

代表父类的构造函数,super内部的this指向子类的实例,只能在构造方法中调用

class Son extends Father {
    constructor(...args) {
      super(...args)
  }
}
  • 子类必须在 constructor 中最先调用 super 方法,否则会报错(引擎规定)
    • 只有调用了super后,才能使用this
    • 如果子类没有定义 constructor,那么就会自动添加一个空的,并且其中自动调用super
  • 等同于借用构造函数,将父类的实例属性添加到子类实例上 Father.prototype.constructor.call(this)

作为对象

在普通方法中,指向父类的原型;静态方法中,指向父类

class Father {
    p () {
      return 123
  }
}

class Son extends Father {
    constructor() {
    super();
    console.log(super.p()); // 等价于 Father.prototype.p()
  }
}
  • 在普通方法中,通过super调用父类的方法时,内部的this指向当前的子类实例
  • 在静态方法中,this指向当前子类
  • 使用 super 时,必须显式指制定是作为函数还是对象使用,否则会报错:console.log(super)