You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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,提问作者서다운

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 04:07:03