无法在Node.js中的ES6中定义的类中调用方法

时间:2016-09-21 16:24:32

标签: javascript node.js express ecmascript-6 es6-class

我正在使用Node.js,Express.js和MongoDB创建应用程序。 我正在使用MVC模式,并且还有单独的路由文件。 我正在尝试创建一个Controller类,其中一个方法调用在其中声明的另一个方法。但我似乎无法做到这一点。我得到“无法读取未定义的属性”。

index.js文件

let express = require('express');
let app = express();

let productController = require('../controllers/ProductController');

app.post('/product', productController.create);

http.createServer(app).listen('3000');

ProductController.js文件

class ProductController {
  constructor(){}

  create(){
   console.log('Checking if the following logs:');
   this.callme();
  }

 callme(){
  console.log('yes');
 }
}
module.exports = new ProductController();

当我运行时,我收到以下错误消息:

Cannot read property 'callme' of undefined

我已经运行了这段代码,只需要进行一些修改,如下所示,它可以工作。

class ProductController {
  constructor(){}
  create(){
    console.log('Checking if the following logs:');
    this.callme();
  }

  callme(){
    console.log('yes');
  }
}
let product = new ProductController();
product.create();

为什么一个工作而另一个工作? 帮助!

2 个答案:

答案 0 :(得分:4)

您的方法是being rebound to the Layer class within express,失去了原来的背景。表达路由的方式是将每个路由包装在Layer类中,该类将路由回调分配给自己:

this.handle = fn;

这就是问题出现的地方,这个赋值会自动将函数上下文重新绑定到Layer。这是一个展示问题的简单示例:

function Example() { 
   this.message = "I have my own scope"; 
} 
Example.prototype.logThis = function() { 
   console.log(this); 
}

function ReassignedScope(logThisFn) { 
   this.message = "This is my scope now";
   // simulation of what is happening within Express's Layer
   this.logThis = logThisFn; 
}

let example = new Example()
let scopeProblem = new ReassignedScope(example.logThis);

scopeProblem.logThis(); // This is my scope now

其他人已经指出了解决方案,即将您的方法显式绑定到ProductController实例:

app.post('/product', productController.create.bind(productController));

答案 1 :(得分:2)

当您将create方法作为方法传递时,可能会按照您的预期在不同的上下文(this)中调用它。你可以绑定它:

app.post('/product', productController.create.bind(productController));

还有很多其他方法可以确保this引用正确的对象。

E.g。用功能(箭头或经典)包装它:

app.post('/product', (...args) => productController.create(...args));

或者在构造函数中绑定方法:

constructor() {
    this.create = this.create.bind(this);
}