2016-09-21 106 views
6

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

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

你应该[从未出口类实例](http://stackoverflow.com/a/39079929/1048572)。要么导出类本身,要么仅使用对象。 – Bergi

回答

2

你的方法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)); 
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); 
} 
相关问题