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