类
类是 ES6 提出的 OOP 语法糖,本质依然是函数,但是与传统的构造函数有所不同
基本语法
javascript
class MyClass {
// 字段
prop = value
// 私有字段
#privateProp = value
// 构造函数
constructor() {
// ...
}
// 方法
method() {
// ...
}
// 私有方法
#privateMethod() {
// ...
}
// getter
get prop() {
return this._prop
}
// setter
set prop(value) {
this._prop = value
}
// 计算属性
['computed' + 'Prop']() {
return 'computed prop'
}
// 静态字段
static staticProp = value
// 静态方法
static staticMethod() {
// ...
}
}
继承
javascript
class Animal {
constructor(name) {
this.name = name
}
speak() {
console.log(this.name + ' makes a noise.')
}
}
class Dog extends Animal {
speak() {
console.log(this.name + ' barks.')
}
}
const d = new Dog('Mitzie')
d.speak() // Mitzie barks.
console.log(Dog.__proto__ === Animal) // true
console.log(Dog.prototype.__proto__ === Animal.prototype) // true
如果一个类扩展了另一个类并且没有 constructor,那么将生成下面这样的“空” constructor:
javascript
class Dog extends Animal {
// 自动生成一个 constructor,即将接收到的参数传递给父类的 constructor
constructor(...args) {
super(...args)
}
speak() {
console.log(this.name + ' barks.')
}
}
一旦在子类中定义了 constructor,那么就必须调用 super
方法,且在使用 this
之前调用,否则会报错
- 当通过 new 执行一个常规函数时,它将创建一个空对象,并将这个空对象赋值给 this。
- 但是当继承的 constructor 执行时,它不会执行此操作。它期望父类的 constructor 来完成这项工作。
类和普通对象的方法有内部属性 [[HomeObject]]
,它记住了方法所属的类/对象,这样就可以在继承时使用 super
正确地调用父类的方法。
一定要区别类/对象的方法和属性:
javascript
class Animal {
hello() {
console.log('animal')
}
}
class Dog extends Animal {
hello() {
super.hello()
}
}
const d = new Dog()
d.hello() // animal
class Cat extends Animal {
hello = function () {
super.hello() // Uncaught SyntaxError: 'super' keyword unexpected here
}
}
const c = new Cat()
c.hello()
私有属性和方法
私有属性和方法是指只能在类的内部访问的属性和方法,ES6 中可以通过在属性名前加 #
来定义私有属性和方法。
javascript
class Counter {
#count = 0
#inc() {
this.#count++
}
inc(){
this.#inc()
}
get value() {
return this.#count
}
}
## 参考
- [现代 JavaScript 教程](https://zh.javascript.info/class)