Skip to content

class 基本语法

在日常开发中,我们经常需要创建许多相同类型的对象,例如用户(users)、商品(goods)或者任何其他东西。

  • 在 ES5 中,可以通过 new function 可以实现这种需求。
  • 在 ES6 中,可以通过 “类 class” 的构造方式。

class 语法

js
class MyClass {
  prop = value; // 属性

  constructor(...) { // 构造器
    // ...
  }

  method(...) {} // method

  get something(...) {} // getter 方法
  set something(...) {} // setter 方法

  [Symbol.iterator]() {} // 有计算名称(computed name)的方法(此处为 symbol)
  // ...
}

上述例子,从技术上来说,MyClass 是一个函数(我们提供作为 constructor 的那个),而 methodsgetterssetters 都被写入了 MyClass.prototype

类的方法之间没有逗号

对于新手开发人员来说,常见的陷阱是在类的方法之间放置逗号,这会导致语法错误。

不要把这里的符号与对象字面量相混淆。在类中,不需要逗号。

类表达式

就像函数一样,类可以在另外一个表达式中被定义,被传递,被返回,被赋值等。

js
let User = class {
  sayHi() {
    alert('Hello')
  }
}

类似于命名函数表达式(Named Function Expressions),类表达式可能也应该有一个名字。

如果类表达式有名字,那么该名字仅在类内部可见:

js
// “命名类表达式(Named Class Expression)”
// (规范中没有这样的术语,但是它和命名函数表达式类似)
let User = class MyClass {
  sayHi() {
    alert(MyClass) // MyClass 这个名字仅在类内部可见
  }
}

new User().sayHi() // 正常运行,显示 MyClass 中定义的内容

alert(MyClass) // error,MyClass 在外部不可见

我们甚至可以动态地“按需”创建类,就像这样:

js
function makeClass(phrase) {
  // 声明一个类并返回它
  return class {
    sayHi() {
      alert(phrase)
    }
  }
}

// 创建一个新的类
let User = makeClass('Hello')

new User().sayHi() // Hello

Getters/Setters

js
class User {
  constructor(name) {
    // 调用 setter
    this.name = name
  }

  get name() {
    return this._name
  }

  set name(value) {
    if (value.length < 4) {
      alert('Name is too short.')
      return
    }
    this._name = value
  }
}

let user = new User('John')
alert(user.name) // John

user = new User('') // Name is too short.

从技术上来讲,这样的类声明可以通过在 User.prototype 中创建 Getters/Setters 来实现。

计算属性名称 […]

和对象字面量类似。

js
class User {
  ['say' + 'Hi']() {
    alert('Hello')
  }
}

new User().sayHi()

prop 属性

例如,让我们在 class User 中添加一个 name 属性:

js
class User {
  name = 'John'

  sayHi() {
    alert(`Hello, ${this.name}!`)
  }
}

new User().sayHi() // Hello, John!

也可以在赋值时使用更复杂的表达式和函数调用:

js
class User {
  name = prompt('Name, please?', 'John')
}

let user = new User()
alert(user.name) // John

method 方法

JavaScript 中的函数具有动态的 this,它取决于调用上下文。

js
class Button {
  constructor(value) {
    this.value = value
  }

  click() {
    alert(this.value)
  }
}

let button = new Button('hello')

setTimeout(button.click, 1000) // undefined

如上代码中的 click 方法会存在 “丢失 this” 的问题,可利用箭头函数来解决:

js
class Button {
  constructor(value) {
    this.value = value
  }

  click = () => {
    alert(this.value)
  }
}

let button = new Button('hello')

setTimeout(button.click, 1000) // hello

基于 MIT 许可发布