在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);
});
在回调函数中,您可以调用this.update
。我知道在这种情况下你应该使用常规(不是ES6箭头)样式的函数定义,如上所示。
但出于好奇,你如何使用ES6箭头函数语法使代码工作?如果我尝试如下操作,我会TypeError: Cannot read property 'update' of undefined
,因为this
当然与上述不同。
traverse(obj).forEach((x) => {
if (x < 0) this.update(x + 128);
});
我尝试使用this
更改bind
,但未成功。如何在ES6箭头功能中更改this
?
答案 0 :(得分:8)
如何更改ES6箭头功能中的
this
?
你不能,这是使用箭头功能的全部要点(除了简洁的语法)。如果您需要控制this
,请不要使用箭头功能。
答案 1 :(得分:2)
ES6中的箭头功能有lexical this。这意味着您可以通过询问问题“定义函数时this
的值是多少?”来告诉他们的this
- 值。它们不受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
。因此,绑定this
的值不应该有任何影响。通过在函数定义之前“冻结”“this”的值,我们阻止了通过绑定,使用call / apply或将函数作为方法调用来更改函数行为的能力。
请注意baz
如何将此值简单地替换为undefined
。那是因为如果我们问问题“定义函数时this
的价值是多少?”,我们显然必须回答undefined
或某些全局对象上下文,如Node global
或浏览器的window
。通过提出这个问题,您可以轻松地推导出箭头函数中this
的值,这是其固有价值的重要组成部分。
因此输出:
{ bar: [Function: bar], baz: [Function: baz] }
-------
undefined
-------
{ bar: [Function: bar], baz: [Function: baz] }
-------
{ i: 1 }
-------
undefined
第一个和第三个输出对应bar()
中定义的箭头函数。请注意他们如何自动拥有this
- 值,该值指向foo
引用的对象,因为它们是使用foo.bar()
调用创建的。有用吗?只能通过绑定更改非箭头功能的行为。在绑定之前,它是this
- 值是undefined
,这是传递函数时许多JS错误和冗余绑定的常见原因。箭头功能带来了很多麻烦。