箭头功能retain the this
of the 周围执行上下文 https://people.mozilla.org/~jorendorff/es6-draft.html#sec-execution-contexts从它们被宣布时起。他们没有改变this
一直如此,就像正常方法一样。
在您的示例中,周围没有执行上下文foo
, so this
is undefined
。这与使用声明的函数具有相同的行为function
关键字处于相同的范围并以相同的方式调用。您可以使用以下方法进行测试:
let foo = () => { return this; }
console.log(foo() === undefined);
From 2016 年 2 月 14 日的规范 https://people.mozilla.org/~jorendorff/es6-draft.html#sec-arrow-function-definitions-runtime-semantics-evaluation:
ArrowFunction 中对参数、super 或 this 的任何引用都必须解析为词法封闭环境中的绑定。通常这将是直接封闭函数的函数环境.
(强调我的)
有趣的是,当该箭头函数出现在全局范围内时,BabelJS 转译器 https://babeljs.io/简单地输出
"use strict";
var foo = function foo() {
return undefined;
};
好像这是唯一正确的行为。阅读规范,它似乎并不那么严格,但这似乎确实是正确的做法。
如果您设法使用不带模块的箭头运行 ES6 代码,那么您似乎最终可以得到这样的全局对象。每10.2.1 的规范 http://people.mozilla.org/~jorendorff/es6-draft.html#sec-strict-mode-code:
- 如果全局代码以包含使用严格指令的指令序言开头(请参阅 14.1.1),则全局代码是严格模式代码。
- 模块代码始终是严格模式代码。
原来如此possible在非严格上下文中获取 ES6 代码。如果发生这种情况,那么this
将使用经典后备并设置为window
(in 规格为 9.2 http://people.mozilla.org/~jorendorff/es6-draft.html#sec-ecmascript-function-objects作为一个未定义的[[ThisMode]]
).
在这个例子中,没有立即封闭的函数,因此没有词法范围可供选择,所以this
最终未定义。
在你的第二个例子中,捕获this
没有什么区别:
let o = {
foo: function() {
var self = this;
console.log(self);
},
bar() {
console.log(this);
}
};
The var self
语句位于函数内,因此它不会执行任何操作。如果你要做:
let o = {
foo: function() {
var self = this;
return function() {
console.log(self);
}
}(),
bar() {
console.log(this);
}
};
那么它将具有您期望的行为(大致),尽管this
仍然是未定义的(或全局对象),因为你不在要捕获的词法环境中。
如果你要使用
class Foo {
bar() {
let baz = () => { return this; }
}
}
then bar
可以转译为
function bar() {
var _this = this;
var baz = function baz() {
return _this;
};
}
哪个做你做的事want。这只有在需要捕获周围环境的情况下才有效。