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

TypeScript函数声明this报undefined 如何修改getDB解决

问题描述

我正尝试通过示例理解TypeScript官方文档中「在函数中声明this」章节的内容。
以下是我编写的测试代码:

class User {
    id: number;
    admin: boolean;

    constructor(id: number, admin: boolean) {
        this.id = id;
        this.admin = admin;
    }

    becomeAdmin() {
        this.admin = true;
    }
}

interface DB {
    filterUsers(filter: (this: User) => boolean): User[];
}

function getDB(): DB {
    return {
        filterUsers: function(filter: (this: User) => boolean) {
            const users = [new User(1, false), new User(2, true)];
            return users.filter(filter);
        }
    }
}

const db = getDB();
const admins = db.filterUsers(function(this: User) {
    return this.admin;
});

console.log(admins);

我预期代码运行后会打印输出[{id: 2, admin: true}],但实际运行时this为undefined,触发了运行错误。
请问该报错的产生原因是什么?应当如何修改getDB()函数来解决这个问题?

报错原因
  • TypeScript中函数参数列表首位的this: 类型标注仅用于静态类型检查,编译为JavaScript后会被完全擦除,不会自动生成任何绑定this的运行时代码。
  • 原实现直接将filter回调传入Array.prototype.filter,该方法执行回调时默认不会绑定自定义this值,ES严格模式下未绑定的this会指向undefined,访问this.admin自然会抛出错误。
  • 额外注意:Array.prototype.filter虽然支持传入第二个参数作为回调固定的this值,但该值会应用到所有遍历项上,不符合我们需要逐个判断用户、每个回调this指向当前遍历用户的需求。
修复方案

修改getDB()中filterUsers的实现,遍历用户列表时,手动通过Function.prototype.call将当前遍历到的User实例绑定为filter回调的this即可,修改后的代码如下:

function getDB(): DB {
    return {
        filterUsers: function(filter: (this: User) => boolean) {
            const users = [new User(1, false), new User(2, true)];
            // 遍历时为每个用户单独绑定回调this
            return users.filter(user => filter.call(user));
        }
    }
}

修改后运行代码,即可得到预期输出[{id: 2, admin: true}]。


内容的提问来源于stack exchange,提问作者Jason Kim

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 17:03:22