我想稍微清理一下我的项目,现在我尝试将es6类用于我的路由。我的问题是这总是未定义的。
var express = require('express');
var app = express();
class Routes {
constructor(){
this.foo = 10
}
Root(req, res, next){
res.json({foo: this.foo}); // TypeError: Cannot read property 'foo' of undefined
}
}
var routes = new Routes();
app.get('/', routes.Root);
app.listen(8080);
尝试使用代码来固定this
:
app.get('/', routes.Root.bind(routes));
您可以使用下划线bindAll函数退出样板。例如:
var _ = require('underscore');
// ..
var routes = new Routes();
_.bindAll(routes)
app.get('/', routes.Root);
我还发现es7允许您以更优雅的方式编写代码:
class Routes {
constructor(){
this.foo = 10
}
Root = (req, res, next) => {
res.json({foo: this.foo});
}
}
var routes = new Routes();
app.get('/', routes.Root);
发生这种情况是因为您已经将一个方法作为独立函数传递来表达。 Express不知道它来自哪个类,因此在调用方法时它不知道使用哪个值作为this
。
你可以用this
强制bind
的值。
app.get('/', routes.Root.bind(routes));
或者您可以使用替代构造来管理路线。在没有类的情况下,您仍然可以利用面向对象编程的许多语法优势。
function Routes() {
const foo = 10;
return {
Root(req, res, next) {
res.json({ foo });
}
};
}
const routes = Routes();
app.get('/', routes.Root);
app.listen(8080);
this
的价值new
调用函数无关紧要bind
的复杂性有一个很好的资源列表here,为什么ES6类不如它们看起来那么好。
或者,如果您不喜欢为每个路由绑定上下文,您可以选择将其绑定到类的构造函数本身中的方法。
E.g:
constructor() {
this.foo = 10;
this.Root = this.Root.bind(this);
}
上面的答案似乎有点复杂。看看我在这里做了什么:
class Routes {
constructor(req, res, next) {
this.req = req;
this.res = res;
this.next = next;
this.foo = "BAR"
// Add more data to this. here if you like
}
findAll (){
const {data, res,} = this; // Or just reference the objects directly with 'this'
// Call functions, do whaterver here...
// Once you have the right data you can use the res obejct to pass it back down
res.json ({foo: this.foo}); // Grabs the foo value from the constructor
}
}
现在,在使用这个类时,您可以按照以下方式执行操作:
var express = require('express');
var router = express.Router();
var {Routes} = require('./Routes');
router.get('/foo', (req, res, next) => {
new Routes(req, res, next).findAll();
});
我会分开这两个文件,所以你只需要将Routes
类放入你的Router
文件中。
希望这有帮助!