Kar*_*awg 18 javascript this undefined node.js es6-class
我试图搜索似乎整个互联网的内容,但我仍然对JS类的问题感到烦恼,我正在为微服务写作(仍在学习中).
所以,我尝试在实例化的对象上调用一个类方法,并根据我的知识和我的(我猜错的)单元测试它应该工作.
好吧,我将从收到的错误开始:
GET /api/users 500 2.863 ms - 2649
TypeError: Cannot read property 'repository' of undefined
at list (C:\Users\<user>\Documents\Programming\node\kaguwa-ngn\kaguwa-user-service\controllers\user-controller.js:20:9)
at Layer.handle [as handle_request] (C:\Users\<user>\Documents\Programming\node\kaguwa-ngn\kaguwa-user-service\node_modules\express\lib\router\layer.js:95:5)
at next (C:\Users\<user>\Documents\Programming\node\kaguwa-ngn\kaguwa-user-service\node_modules\express\lib\router\route.js:137:13)
Run Code Online (Sandbox Code Playgroud)
(还有更多).
代码调用代码:
user-controller.js
'use strict';
var utils = require('./utils');
class UserController {
constructor(repository) {
this.repository = repository || {};
}
/**
*
* Lists all users.
*
* @param {object} req
* @param {object} res
*/
list(req, res) {
this.repository.list(function (err, users) {
if (err) return res.status(500).json(utils.createError(500));
if (Object.keys(users).length !== 0) {
res.json(users);
} else {
res.status(404).json(utils.createNotFound('user', true));
}
});
}
// more code
}
module.exports = UserController
Run Code Online (Sandbox Code Playgroud)
控制器的来电者
user-api.js
'use strict';
var express = require('express');
var UserController = require('../controllers/user-controller');
var router = express.Router();
module.exports = function (options) {
var userController = new UserController(options.repository);
router.get('/users', userController.list);
// Mode code
return router;
};
Run Code Online (Sandbox Code Playgroud)
我真的不知道为什么this未定义UserController.
任何帮助都会受到极大的关注.
jfr*_*d00 42
当你这样做:
router.get('/users', userController.list);
Run Code Online (Sandbox Code Playgroud)
传递给路由器的只是对.list方法的引用.userController实例丢失了.这不是路由器所特有的 - 这是Javascript中传递内容的通用属性.要进一步了解,您实际上在做的是:
let list = userController.list;
// at this point the list variable has no connection at all to userController
router.get('/users', list);
Run Code Online (Sandbox Code Playgroud)
并且,在Javascript的strict模式下,当你调用一个没有任何对象引用的常规函数时,如list()上面的调用,那么this将undefined在函数内部.这就是你的例子中发生的事情.要修复它,您需要确保使用适当的对象引用调用方法,userController.list(...)以便解释器this适当地设置值.
有多种方法可以解决此问题:
制作自己的函数包装器
router.get('/users', function(req, res) {
userController.list(req, res);
});
Run Code Online (Sandbox Code Playgroud)
这适用于任何版本的Javascript.
.bind()用于为您创建一个使用正确对象调用它的包装器
router.get('/users', userController.list.bind(userController));
Run Code Online (Sandbox Code Playgroud)
这适用于ES5 +或.bind()polyfill.
使用ES6箭头功能快捷方式
router.get('/users', (...args) => userController.list(...args));
Run Code Online (Sandbox Code Playgroud)
这适用于ES6 +
就个人而言,我更喜欢.bind()实现,因为我认为它比其他任何一个更简单,更具说服力/更清晰,而且ES6"快捷方式"并不是真的更短.
| 归档时间: |
|
| 查看次数: |
6483 次 |
| 最近记录: |