Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/428.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 无法在Node.js的ES6中定义的类中调用方法_Javascript_Node.js_Express_Ecmascript 6_Es6 Class - Fatal编程技术网

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

Javascript 无法在Node.js的ES6中定义的类中调用方法,javascript,node.js,express,ecmascript-6,es6-class,Javascript,Node.js,Express,Ecmascript 6,Es6 Class,我正在使用Node.js、Express.js和MongoDB制作一个应用程序。 我使用的是MVC模式,也有单独的路由文件。 我正在尝试创建一个控制器类,其中一个方法调用其中声明的另一个方法。但我似乎无法做到这一点。我得到“无法读取未定义的属性” index.js文件 let express = require('express'); let app = express(); let productController = require('../controllers/ProductCont

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

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();
为什么一个有效而另一个无效?
救命啊

当您将
create
方法传递为方法时,可能会在不同的上下文(
this
)中调用它,正如您所期望的那样。您可以绑定它:

app.post('/product', productController.create.bind(productController));
还有许多其他方法可以确保
引用了正确的对象

例如,使用函数(箭头或经典)包装:

或构造函数中的绑定方法:

constructor() {
    this.create = this.create.bind(this);
}
您的方法正在丢失其原始上下文。express处理路由的方式是将每个路由包装在一个
类中,该类将路由回调分配给自身:

this.handle = fn;
这就是问题所在,此赋值会自动将函数上下文重新绑定到
。下面是一个简单的示例,演示了该问题:

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));

你应该。导出类本身或仅使用对象。您应该使用属性初始值设定项语法(
callme=()=>{…}
而不是像这样定义类内的方法
callme(){…}
)。
app.post('/product', productController.create.bind(productController));