JavaScript静态块执行期间,为何无法访问当前类的静态方法?
类静态块执行时引用未初始化类的问题分析与解决
问题代码
class B { foo() { return A.foo(); // 报错:Uncaught ReferenceError: A is not defined } } class A { static { console.log(new B().foo()); } static foo() { return "foo"; } }
错误根源
这不是类有没有完成声明的问题,而是**类的初始化时机和暂时性死区(TDZ)**的限制:
- 类声明确实会被提升,但提升后会进入暂时性死区,只有当代码执行到类定义的位置时,才会启动类的初始化流程——包括绑定静态属性/方法、执行静态块。
- 当
class A的静态块执行时,A类处于正在初始化的状态:此时静态块是初始化流程的一部分,整个A类还没完成初始化。这时候通过new B().foo()间接访问A,相当于从外部访问一个正在初始化的类,会触发暂时性死区的引用错误,哪怕A已经被声明。 - 另外,就算忽略TDZ问题,静态块写在
static foo()前面,执行静态块时A.foo还没被定义,后续也会出现A.foo is not a function的错误。
解决办法
1. 调整静态块到静态方法之后
把静态块放在所有静态方法/属性的后面,这样执行静态块时,A的静态方法已经绑定完成,同时A类的初始化进度也能允许外部访问:
class B { foo() { return A.foo(); } } class A { static foo() { return "foo"; } static { console.log(new B().foo()); // 正常输出"foo" } }
2. 延迟调用,等A完成初始化
如果不能调整代码顺序,可以用微任务把调用推迟到事件循环的下一轮,此时A已经完成初始化:
class B { foo() { return A.foo(); } } class A { static { queueMicrotask(() => { console.log(new B().foo()); // 正常输出"foo" }); } static foo() { return "foo"; } }
3. 先完成A的初始化再定义B
把B的定义放到A的静态块里,确保A初始化完成后再创建B类:
let B; class A { static foo() { return "foo"; } static { B = class { foo() { return A.foo(); } }; console.log(new B().foo()); // 正常输出"foo" } }
内容的提问来源于stack exchange,提问作者서다운
相关产品推荐
相关产品推荐

