2016-09-21 37 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); 
} 
相關問題