JavaScript类内定义方法访问自身触发ReferenceError如何修复
问题原因
这个报错由ES类的固定初始化顺序导致:
- 类定义执行时,会先完成所有实例成员(实例方法、实例字段)的计算属性名求值,这个阶段早于所有静态字段的初始化,此时类名
Action仍处于临时死区(TDZ),禁止访问,因此直接在实例方法的计算属性名位置引用Action会抛出引用错误。 - 静态字段按代码书写顺序依次初始化,你定义的
static buttonSession写在static actionSelector之后,执行到这行时Action已经完成前置初始化、actionSelector也已经赋值完成,所以可以正常访问。
你尝试的两种写法不生效的原因:
[this.actionSelector.buttonCommit]:类体中计算属性名的求值上下文里,this指向类定义所在外层作用域的this(模块环境下为undefined,全局环境下为全局对象),并非Action类本身,自然找不到actionSelector属性。[this.constructor.actionSelector.buttonCommit]:同样是this指向错误,计算属性名求值阶段还未创建任何类实例,不存在指向构造函数的constructor属性。
修复方案
不需要把actionSelector移到全局作用域,使用类静态初始化块挂载实例方法即可。静态块会按照静态成员的书写顺序执行,执行到静态块时Action已经完成初始化,可以正常访问静态属性:
class Action extends PublishableAction { static actionSelector = { buttonCommit: Symbol() }; static buttonSession = Action.viewController({ perform: Action.actionSelector.buttonCommit }); // 静态块在前面的静态字段初始化完成后执行,此时可正常访问Action static { // 给类原型挂载方法,效果和类内直接定义实例方法完全一致 Action.prototype[Action.actionSelector.buttonCommit] = function() { // 原方法逻辑写在这里 // 注意不要使用箭头函数,否则方法内this无法指向类实例,会和普通实例方法的行为不一致 // ... } } }
补充说明:
- 静态块是和类静态字段同版本的ES2022标准特性,所有支持静态字段的运行环境(现代浏览器、Node.js 16+)都可以直接使用,不需要额外兼容。
- 原代码计算属性名位置写的
buttomCommit是拼写错误,正确属性名为buttonCommit,需要修正避免后续方法匹配失败。
内容的提问来源于stack exchange,提问作者Smally
相关产品推荐
相关产品推荐

