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
相关产品推荐
相关产品推荐

