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文章 :“箭头函数捕获封闭上下文的这个值”
- “React-Native 0.16.0和0.17.0”中的“babelHelpers.asyncToGenerator不是一个函数”
- 当使用文件的绝对path时,babel-node失败
- babel-node无法find模块 – 将预设选项解释为文件名?
- 与Webpack和Babel一起使用Benchmarkjs
- 在node.js(ES6 / Babel)中inputX和input*之间的区别是X?
- 伊斯坦布尔与巴贝尔有什么关系?
- 告诉react-native打包者观看一个非javascript文件
- 我应该在npm上发布模块的源代码吗?
- 用于在node_modules中编译模块的Webpackconfiguration