Node后端TypeScript中非箭头类方法this为undefined的问题
嘿,这个问题其实是JavaScript/TypeScript里this绑定的典型场景,我来帮你把这两个疑问拆解明白!
1. 为什么非箭头方法中的this是undefined?
你写的第一个版本里,getUsers是类的普通方法,当你把UserController.getUsers作为参数传给userRouter.get的时候,本质上是把这个方法从实例上单独提取了出来——它不再和UserController的实例绑定在一起了。
在JavaScript的函数调用规则里,当一个函数被独立调用(不是作为对象的方法调用,比如obj.fn()这种形式),this的绑定会遵循默认绑定规则。而Node.js的模块默认是启用严格模式的,在严格模式下,默认绑定的this就是undefined,而不是全局对象(浏览器里非严格模式才会指向window)。
简单说:路由框架调用getUsers的时候,是直接调用这个函数,而不是通过UserController.getUsers()的形式,所以this丢失了和实例的绑定,变成了undefined。
2. 为什么箭头方法能正常工作?
箭头函数的this规则和普通函数完全不一样:它不会自己绑定this,而是在定义时捕获当前作用域的this值。
在类里定义箭头函数作为字段时,这个字段的初始化是在类的构造函数执行阶段完成的。当new UserController()执行构造函数的时候,当前作用域的this就是刚创建出来的UserController实例,所以箭头函数getUsers会把这个this捕获下来,之后不管这个箭头函数被传到哪里调用,它的this都会一直指向这个实例,自然就能正常调用this.processRequest了。
额外的解决方案
除了用箭头函数,你还有两种常见的方式解决这个问题:
- 手动绑定
this:在导出实例的时候,把方法绑定到实例上,比如:const userController = new UserController(); userController.getUsers = userController.getUsers.bind(userController); export default userController; - 在路由里用箭头函数包裹调用:
这样调用userRouter.get('/', authMiddleWare, (req, res) => UserController.getUsers(req, res));getUsers的时候,是通过UserController.getUsers()的形式,this会自动绑定到实例上。
内容的提问来源于stack exchange,提问作者Jonnopon3000

