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

TypeScript静态方法导出后运行报错:this为undefined的原因与解决

问题原因分析

当你把ConcreteFoo.foo作为单独的函数导出并调用时,静态方法的this上下文丢失了。

在JavaScript/TypeScript中,静态方法的this默认指向所属的类(这里是ConcreteFoo),但当你把ConcreteFoo.foo单独提取出来作为一个函数引用时,它的执行上下文不再绑定到ConcreteFoo。在严格模式下(TypeScript编译后的代码默认启用严格模式),独立调用的函数this会变成undefined。

当你在voodoo.ts中调用voodoo("whatisthis")时,实际是在无上下文的情况下执行foo方法,此时super.foo(param)调用AbstractFoo.foo时,里面的this.plzOverrideMe()中的this就是undefined,自然会抛出无法读取plzOverrideMe的错误。

解决方案

提供三种可行的修复方式:

1. 绑定this到类

修改concretefoo.ts的导出语句,通过bind方法把foo函数的this固定绑定到ConcreteFoo:

// concretefoo.ts
import { AbstractFoo } from "./abstractfoo"

class ConcreteFoo extends AbstractFoo {
    public static override foo(param: string) {
        super.foo(param);
    }

    protected static override plzOverrideMe() {
        return "blah";
    }
};

export default ConcreteFoo.foo.bind(ConcreteFoo); // 绑定this

2. 使用箭头函数包装

通过箭头函数捕获ConcreteFoo的上下文,调用时自动保留正确的this:

// concretefoo.ts
import { AbstractFoo } from "./abstractfoo"

class ConcreteFoo extends AbstractFoo {
    public static override foo(param: string) {
        super.foo(param);
    }

    protected static override plzOverrideMe() {
        return "blah";
    }
};

export default (param: string) => ConcreteFoo.foo(param); // 箭头函数包装

3. 直接导出类并调用静态方法

调整concretefoo.ts导出整个类,在voodoo.ts中直接通过类调用静态方法,确保上下文不丢失:

// concretefoo.ts
import { AbstractFoo } from "./abstractfoo"

export default class ConcreteFoo extends AbstractFoo { // 导出类
    public static override foo(param: string) {
        super.foo(param);
    }

    protected static override plzOverrideMe() {
        return "blah";
    }
};
// voodoo.ts
import ConcreteFoo from "./concretefoo"

ConcreteFoo.foo("whatisthis"); // 通过类调用静态方法

以上三种方式都能让AbstractFoo.foo中的this正确指向ConcreteFoo,从而调用到重写后的plzOverrideMe方法,输出预期的"blah"。

内容的提问来源于stack exchange,提问作者404 Name Not Found

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 01:55:18