ES6方法得到一个空“这个”和类variables是无法访问的

我正在使用ES6类将一些function绑定在Node中。 这里(基本上)是这样的:

class processDocs { constructor(id) { this.id = id; // console.log(this) returns { id: id } } getDocs(cb) { // console.log(this) returns null docs .query(qb => { qb.where('id', this.id); }) .fetch() .then(function(documents) { cb(null, documents); }) ; } alterDocs(documents, cb) { //some logic } reindexSearch(cb) { //some logic } process() { // console.log(this) returns { id: id } async.waterfall([ this.getDocs, this.alterDocs, this.reindexSearch ]); } } export default processDocs; 

我认为,与ES6类,分配公共variables的方式是简单地引用this和通过构造函数初始化这些variables的方式正是它是如何显示在我的类定义。

以下是我如何调用这个类(在一个单独的文件中):

 var Processor = require('./processDocs'); var pr = new Processor(id); var docs; pr.process(); 

这是问题,当我console.log从构造函数中,我得到我的{ id: id }值如预测; 不过,每当我在getDocs注销this process运行时,它是空的。 但是,当我在瀑布之前的process()注销this时,我得到了我的原始对象。

这有什么理由吗?

顺便说一句,我使用节点: v0.10.33和babel节点4.6.6 ,我用--harmony标志运行babel节点。 在任何人询问之前,由于v0.10.x上的主要依赖关系,我无法更新到较新的Node版本。

编辑我能够创build一个解决方法,但它不是非常像es6。 这个问题似乎与async.waterfall 。 我不得不用一个.bind来解决它:

  async.waterfall([ this.getDocs.bind(this), this.alterDocs.bind(this), this.reindexSearch.bind(this) ]); 

ES6并没有改变“这个”是如何工作的,因此它取决于“你在哪里调用它”而不是“总是具有相同”的价值。 这是非常不直观的,在其他语言中并不常见。

考虑这个例子

 class processDocs { constructor(id) { this.id = id; console.log(this) } getDocs(cb) { console.log(this) } alterDocs(documents, cb) { //some logic } reindexSearch(cb) { //some logic } process() { console.log(this) } } var process = new processDocs(10); var docs = process.getDocs(function(){}); var processInstance = process.process(); var docsAsFunction = process.getDocs; docsAsFunction(function(){}); 

输出是

 processDocs {id: 10} processDocs {id: 10} processDocs {id: 10} undefined 

正如你所看到的,最后一个是undefines,它叫做“docsAsFunction”,因为你没有直接从它的类中调用这个函数,所以上下文是不同的。

你可以阅读关于它的例子

我创build了以下function。

 let bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }; //from coffeescript's => operator //use in a class's constructor to make the this pointer always refer to the object in which a function resides function fixThisPointer(_this, func){ _this[func.name] = bind(_this[func.name], _this); } function fixThisPointer2(_this, funcNameArray){ for (name of funcNameArray){ _this[name] = bind(_this[name], _this); } } 

然后,当我需要它时,我在构造函数中使用这个命令

 fixThisPointer(this, foo) 

或者这个命令

 fixThisPointer2(this, ['foo', 'foo2', 'foo3']) 

考虑将process()的主体更新为:

 process() { // console.log(this) returns { id: id } async.waterfall([ (cb)=>{this.getDocs(cb);}, (documents,cb)=>{this.alterDocs(documents,cb);}, (cb)=>{this.reindexSearch(cb);} ]); } 

使用箭头函数可确保使用正确的上下文调用类的成员函数。

你可以在你的类中使用箭头函数,因为它们自动绑定这个。 你可以写你的类的方法如下:

  getDocs = (cb) => { // console.log(this) will not returns null docs .query(qb => { qb.where('id', this.id); }) .fetch() .then(function(documents) { cb(null, documents); }) ; } 

看到这个MDN文章 :“箭头函数捕获封闭上下文的这个值”