Nodejs,表达路由为es6类

Mic*_*ura 19 javascript this nodes node.js express

我想稍微清理一下我的项目,现在我尝试将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);
Run Code Online (Sandbox Code Playgroud)

zag*_*art 14

尝试使用代码来固定this:

app.get('/', routes.Root.bind(routes));
Run Code Online (Sandbox Code Playgroud)

您可以使用下划线bindAll函数退出样板.例如:

var _ = require('underscore');

// ..

var routes = new Routes();
_.bindAll(routes, 'Root')
app.get('/', routes.Root);
Run Code Online (Sandbox Code Playgroud)

我还发现es7允许您以更优雅的方式编写代码:

class Routes {
    constructor(){
        this.foo = 10
    }

    Root = (req, res, next) => {
        res.json({foo: this.foo});
    }
}

var routes = new Routes();
app.get('/', routes.Root);
Run Code Online (Sandbox Code Playgroud)


Dan*_*nce 9

发生这种情况是因为您已经将一个方法作为独立函数传递来表达.Express不知道它来自哪个类,因此它不知道this在调用方法时使用哪个值.

你可以强制使用thiswith 的值bind.

app.get('/', routes.Root.bind(routes));
Run Code Online (Sandbox Code Playgroud)

或者您可以使用替代构造来管理路线.在没有类的情况下,您仍然可以利用面向对象编程的许多语法优势.

function Routes() {
  const foo = 10;

  return {
    Root(req, res, next) {
      res.json({ foo });
    }
  };
}

const routes = Routes();
app.get('/', routes.Root);
app.listen(8080);
Run Code Online (Sandbox Code Playgroud)
  • 你不必担心它的价值 this
  • 不要紧的功能是否被调用new或不
  • 您可以避免调用bind每条路由的复杂性

有良好的资源列表在这里,为什么ES6类并不像看上去那么好.


小智 5

import express from 'express';
const app = express();

class Routes {
    constructor(){
        this.foo = 10
    }

    const Root = (req, res, next) => {
        res.json({foo: this.foo}); // TypeError: Cannot read property 'foo' of undefined
    }
}

const routes = new Routes();
app.get('/', routes.Root);
app.listen(8080);
Run Code Online (Sandbox Code Playgroud)

这是对代码的小幅重写,但正如这里的一些答案所指出的那样,在路由配置中像这样引用时,函数本身是不知道的this,必须绑定。为了解决这个问题,您不必编写“普通”函数,而只需编写定义自动绑定自己的“粗箭头”函数,就可以了!

  • 如果你不使用 TS,你似乎不能在类中使用 const 来定义成员函数。我还想指出,在类中使用箭头函数会使该函数“私有”以继承类,即“super.Root()”不起作用。 (2认同)