面试题答案
一键面试定义状态枚举类型
enum State {
Draft = 'Draft',
Submitted = 'Submitted',
Discarded = 'Discarded',
Approved = 'Approved',
Rejected = 'Rejected',
Returned = 'Returned'
}
实现 canTransition
函数
function canTransition(from: State, to: State): boolean {
const transitionRules: { [key in State]: State[] } = {
[State.Draft]: [State.Submitted, State.Discarded],
[State.Submitted]: [State.Approved, State.Rejected, State.Returned]
};
return transitionRules[from]?.includes(to) || false;
}
使用枚举类型的优点
- 类型安全:枚举类型提供了类型检查,减少错误发生的可能性。比如在
canTransition
函数中,传入的参数类型必须是定义好的枚举值,否则会报错。 - 可读性:使用有意义的枚举名称,比直接使用字符串或数字更具可读性。例如
State.Draft
比字符串'Draft'
更能清晰表达其含义。 - 可维护性:当状态需要修改或扩展时,只需要在枚举定义中进行修改,而不需要在使用的地方逐个修改硬编码的值。
使用枚举类型的缺点
- 灵活性有限:枚举类型一旦定义,其值相对固定。如果需要动态生成状态,枚举就不太适用。
- 编译后代码体积:在编译成JavaScript后,枚举类型会生成额外的代码,可能会增加代码体积。
替代方案
- 对象字面量:可以使用对象字面量来定义状态。例如:
const state = {
Draft: 'Draft',
Submitted: 'Submitted',
Discarded: 'Discarded',
Approved: 'Approved',
Rejected: 'Rejected',
Returned: 'Returned'
};
优点是更灵活,可以动态添加或修改属性。缺点是类型安全性不如枚举,需要手动进行类型检查。 2. 类:可以使用类来封装状态和状态转换逻辑。例如:
class StateMachine {
private states = {
Draft: 'Draft',
Submitted: 'Submitted',
Discarded: 'Discarded',
Approved: 'Approved',
Rejected: 'Rejected',
Returned: 'Returned'
};
canTransition(from: string, to: string): boolean {
const transitionRules: { [key: string]: string[] } = {
[this.states.Draft]: [this.states.Submitted, this.states.Discarded],
[this.states.Submitted]: [this.states.Approved, this.states.Rejected, this.states.Returned]
};
return transitionRules[from]?.includes(to) || false;
}
}
优点是可以封装更多的逻辑和行为,缺点是相对复杂,代码量可能会增加。