主题
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 的那个),而 methods
、getters
和 setters
都被写入了 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