Node.js创建可复用控制器时类实例this指向异常问题求助
问题原因与解决方案
问题根源
当你把userController.signIn这类控制器方法直接作为路由处理函数传递给Express的router.post时,方法的**this上下文会脱离原控制器实例**。此时方法内部的this不再指向userController,自然无法读取到实例上的service和dto属性,导致TypeError。
三种可行解决方案
1. 手动绑定this到控制器实例
在路由中传递方法时,用bind把方法的this绑定到userController实例:
// 路由代码修改如下 router.post('/signup', userController.signup.bind(userController)); router.post('/signin', userController.signIn.bind(userController)); router.post('/signout', userController.signOut.bind(userController)); router.get('/all', userController.getAll.bind(userController)); router.route("/:id") .get(userController.get.bind(userController)) .post(userController.create.bind(userController)) .patch(userController.update.bind(userController)) .delete(userController.delete.bind(userController));
2. 在控制器构造函数中提前绑定方法
在父类MainController的构造函数里,把所有需要用到的方法提前绑定到实例,这样路由里直接传递方法即可:
// MainController示例 export default class MainController { constructor(service, dto) { this.service = service; this.dto = dto; // 绑定所有需要在路由中使用的方法 this.signIn = this.signIn.bind(this); this.signup = this.signup.bind(this); this.signOut = this.signOut.bind(this); this.getAll = this.getAll.bind(this); this.get = this.get.bind(this); this.create = this.create.bind(this); this.update = this.update.bind(this); this.delete = this.delete.bind(this); } }
之后路由代码无需修改,直接传递userController.signIn即可。
3. 用箭头函数包装路由处理函数
在路由中用箭头函数包裹控制器方法调用,箭头函数会保留外层上下文,确保方法内部的this指向控制器实例:
// 路由代码修改如下 router.post('/signup', (req, res) => userController.signup(req, res)); router.post('/signin', (req, res) => userController.signIn(req, res)); router.post('/signout', (req, res) => userController.signOut(req, res)); router.get('/all', (req, res) => userController.getAll(req, res)); router.route("/:id") .get((req, res) => userController.get(req, res)) .post((req, res) => userController.create(req, res)) .patch((req, res) => userController.update(req, res)) .delete((req, res) => userController.delete(req, res));
内容的提问来源于stack exchange,提问作者Azim Umarov
相关产品推荐
相关产品推荐

