`expressJS路由处理程序中未定义this
`this` is undefined in expressJS route handler
groups.js
class groupsCtrl {
constructor() {
this.info = "test";
}
get(res, req) {
console.log("LOG ! ", JSON.stringify(this));
}
}
module.exports = new groupsCtrl(); //singleton
路由.js
var express = require('express');
var router = express.Router();
var groupsCtrl = require('controllers/api_admin/groups.js');
router.get('/groups/', groupsCtrl.get);
此日志记录LOG ! undefined
如何访问控制器类中的this
?
您需要将方法绑定到实例。
一种解决方案:
router.get('/groups/', groupsCtrl.get.bind(groupsCtrl));
另一种解决方案:
constructor() {
this.info = "test";
this.get = this.get.bind(this);
}
或者使用类似es6bindall
的东西(它基本上与上面的代码相同,但在需要绑定多个方法时可能更有用)。
class groupsCtrl {
constructor() {
this.info = 'test';
}
get = (res, req) => {
console.log('LOG ! ', JSON.stringify(this));
};
}
您可以使用箭头函数来避免样板代码
2020更新
- 虽然@robertkiep发布的两个解决方案都没有得到这份工作,但我想强调的是,两者看起来都很难看,而且都不可维护
- 当有大量路由时,执行router.get('/groups/',groupsCtrl.get.bind(groupsCtrl))的方法1看起来非常难看
- 当控制器有许多路由时,方法2会变得麻烦
- 由于你的例子只有一条路线,让我来说明这个问题
使用方法2
class AuthController {
constructor({ db, pgp, logger }) {
super({ db, pgp, logger })
this.postLogin = this.postLogin.bind(this)
this.postLogout = this.postLogout.bind(this)
this.postSignup = this.postSignup.bind(this)
this.postForgot = this.postForgot.bind(this)
this.getReset = this.getReset.bind(this)
this.postReset = this.postReset.bind(this)
}
postLogin(req, res, next) {
}
postLogout(req, res, next) {
}
async postSignup(req, res, next) {
}
async postForgot(req, res, next) {
}
async getReset(req, res, next) {
}
async postReset(req, res, next) {
}
}
每次添加新方法时,构造函数都需要进一步更新
方法3
在我看来,这要干净得多,不需要维护,你可以继续添加你想要的方法
- 其想法是使用Object.hasOwnPropertyName来获取所有方法名称的数组,然后以编程方式绑定它们
- 例如,如果您编写Object.hasOwnPropertyName(AuthController.protype),它将为您提供数组中的所有非静态方法
- 在上面的示例中,您将得到['constructor','postLogin','postLogout'…]
- 如果调用Object.hasOwnPropertyName(AuthController),则会得到STATIC方法
- 让我们以编程方式调用它们
这个控制器几乎不需要维护,只需要记住静态和非静态方法,通过过滤掉构造函数来删除它,然后在每个上调用绑定
class AuthController {
constructor({ db, pgp, logger }) {
super({ db, pgp, logger })
this.postLogin = this.postLogin.bind(this)
this.postLogout = this.postLogout.bind(this)
this.postSignup = this.postSignup.bind(this)
this.postForgot = this.postForgot.bind(this)
this.getReset = this.getReset.bind(this)
this.postReset = this.postReset.bind(this)
Object.getOwnPropertyNames(AuthController.prototype)
.filter((propertyName) => propertyName !== 'constructor')
.forEach((method) => (this[method] = this[method].bind(this)))
}
postLogin(req, res, next) {
}
postLogout(req, res, next) {
}
async postSignup(req, res, next) {
}
async postForgot(req, res, next) {
}
async getReset(req, res, next) {
}
async postReset(req, res, next) {
}
}
上面的答案很好,我想添加一点帮助澄清:
假设我们有一个类:
class TClass {
constructor(arg) {
this.arg = arg
}
test() {
console.log(this.arg)
}
}
这将不起作用:
const t = new TClass("test")
const method = t.test // method is simply a reference without context
method() // 'this' is not defined
这将起作用:
const t = new TClass("test")
t.test() // log 'test'
原因就像上面的注释一样,对函数的引用没有上下文
相关文章:
- this.router在AngularJS 2中未定义
- React+Meteor:this.ops返回未定义
- `当使用箭头函数时,“开发工具”中未定义“this”
- jQuery$(this)引用未定义
- this.defaultValue 返回 select 元素的未定义
- Alt flux action:_this.actions未定义,即使调用了this.generateActions
- $(this).attr({class:“activeTab”});不起作用,因为这是未定义的
- $(this)抛出“;未定义的“;但这是按预期进行的
- jqueryui:"类型错误:this.menu.element未定义"
- this.value在<td>标记显示未定义
- $(this)返回'未定义'
- TypeError:this.clusterer在Rails模型名称更改后未定义
- this._id流星中未定义
- Angular ES6,THIS,Scope和EL在JQLITE点击事件中全部未定义
- this.userId 在 Meteor.publish 中返回未定义
- 为什么我需要将“var value = val;”更改为“this.value = val;”,这样我就不会收到“未定义
- ReactJS - {this.props.children} 是未定义的
- 为什么 this.name 未定义
- `expressJS路由处理程序中未定义this
- 在Route类中未定义this.controller