如何改变ES6箭头函数的“this”指向的是什么?

traverse npm包中有这个例子

 var obj = [ 5, 6, -3, [ 7, 8, -2, 1 ], { f : 10, g : -13 } ]; traverse(obj).forEach(function (x) { if (x < 0) this.update(x + 128); }); 

在callback函数中你可以调用this.update 。 我知道在这种情况下,你应该使用常规(不是ES6箭头)风格的函数定义,如上所示。

但出于好奇,你将如何使用ES6箭头函数语法的代码工作? 如果我尝试如下,我得到TypeError: Cannot read property 'update' of undefined因为当然this是不一样的上面。

 traverse(obj).forEach((x) => { if (x < 0) this.update(x + 128); }); 

我试图通过使用bind来改变this ,但没有成功。 你如何改变ES6的箭头function呢?

你如何改变ES6的箭头function呢?

你不能,那就是使用箭头函数的全部意义(除了简洁的语法外)。 如果您需要控制this ,请勿使用箭头function。

ES6中的箭头function有这个词法 。 这意味着你总是可以通过提出这样的问题来告诉他们this值:“当函数被定义时, this值是多less? 它们对this调用,应用,绑定和方法调用的影响是免疫的。

让我们来看看通过与Babel编译ES6到ES5的预期效果。

ES6:

 let foo = { bar() { return [ () => this, function() { return this } ] }, baz: () => this } let fns = foo.bar() fns.push(...fns.map((fn, i) => fn.bind({i}))) fns.map(fn => fn()).forEach(thisVal => { console.log(thisVal) console.log('-------') }) console.log(foo.baz()) 

编译成ES5:

 'use strict'; function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } var foo = { bar: function bar() { var _this = this; return [function () { return _this; }, function () { return this; }]; }, baz: function baz() { return undefined; } }; var fns = foo.bar(); fns.push.apply(fns, _toConsumableArray(fns.map(function (fn, i) { return fn.bind({ i: i }); }))); fns.map(function (fn) { return fn(); }).forEach(function (thisVal) { console.log(thisVal); console.log('-------'); }); console.log(foo.baz()); 

看看foo.bar里面发生了什么。 有一条插入的行:

 var _this = this; 

箭头函数的主体被改变了,所以它从它的词法外部范围返回。 所以,绑定这个值不应该有任何效果。 通过在函数定义之前“冻结”这个“this”的值,我们已经阻止了通过绑定,使用call / apply或者调用函数作为方法来改变函数行为的能力。

注意baz的这个值是如何被undefined取代的。 这是因为如果我们提出这样的问题:“当函数被定义时, this值是什么?”,我们显然必须回答undefined或全局的对象上下文,比如Node的global或者浏览器的window 。 通过问这个问题,你可以很容易地推断出this箭头函数的价值, this是它们内在价值的一个重要组成部分。

输出是:

 { bar: [Function: bar], baz: [Function: baz] } ------- undefined ------- { bar: [Function: bar], baz: [Function: baz] } ------- { i: 1 } ------- undefined 

第一个和第三个输出对应于bar()定义的箭头函数。 注意它们是如何自动有一个this值指向由foo引用的对象,因为它们是用foo.bar()调用创build的。 有用的权利? 只有非箭头function的行为可以通过绑定来改变。 在绑定之前, this值是undefined ,当传递函数时, this是JS错误和冗余绑定的常见原因。 箭头function带走了很多麻烦。