ProductController中构造函数初始化的ProductService为何在方法中未定义?
问题分析与解决
你遇到的问题是:ProductsController构造函数中初始化的productsService在retrieveProducts方法里始终是undefined,但在方法内重新实例化ProductService就能正常运行。报错信息为:
Error occurred during processing request TypeError: Cannot read properties of undefined (reading 'productService') at findById
本质原因是类方法的this绑定丢失——当你把retrieveProducts作为路由回调函数使用时,它的this不会自动指向ProductsController的实例,导致this.productsService无法访问到构造函数中初始化的实例。
下面是三种可行的解决方法:
方法1:用箭头函数定义类方法
箭头函数会自动捕获外层作用域(类实例)的this,避免绑定丢失问题:
export class ProductsController { productsService: ProductService; constructor() { console.log('Entered constructor ProductsController') this.productsService = new ProductService() } retrieveProducts = async (request: Request, response: Response, next: NextFunction) => { try { const productId = request.params.productId const product = await this.productsService.findById(productId) if(product){ response.status(200).json(product) return } response.status(400).json({message: '未找到对应产品'}) return } catch (error) { console.error('处理请求时发生错误', error) response.status(400).json({message: '处理请求过程中出错'}) } } }
方法2:在构造函数中绑定this
手动将retrieveProducts方法的this绑定到类实例:
export class ProductsController { productsService: ProductService; constructor() { console.log('Entered constructor ProductsController') this.productsService = new ProductService() // 绑定this到当前实例 this.retrieveProducts = this.retrieveProducts.bind(this) } async retrieveProducts(request: Request, response: Response, next: NextFunction){ try { const productId = request.params.productId const product = await this.productsService.findById(productId) if(product){ response.status(200).json(product) return } response.status(400).json({message: '未找到对应产品'}) return } catch (error) { console.error('处理请求时发生错误', error) response.status(400).json({message: '处理请求过程中出错'}) } } }
方法3:注册路由时绑定this
在将方法作为路由回调传递时,通过bind强制绑定类实例:
// 假设使用Express框架 const productsController = new ProductsController() app.get('/products/:productId', productsController.retrieveProducts.bind(productsController))
内容的提问来源于stack exchange,提问作者BreenDeen
相关产品推荐
相关产品推荐

