箭头功能 - 为什么会将全局对象打印到控制台? [英] Arrow functions - why does this print the global object to the console?
问题描述
为什么 o.foo()
将全局对象打印到控制台?
Why does o.foo()
print the global object to the console?
let o = {
foo: () => console.log(this),
bar() { console.log(this); }
};
o.foo(); // Global object / undefined
o.bar(); // o
我认为相当于箭头函数可能是这样的(但不是) :
I thought the equivalent of the arrow function might be something like this (but it's not):
let o = {
foo: function() {
var self = this;
console.log(self);
},
bar() {
console.log(this);
}
};
o.foo(); // o
o.bar(); // o
推荐答案
箭头功能 em> c 这个
。
在你的例子中,没有 foo
之间的执行上下文,所以这个
是 undefined
。这与使用相同范围的函数
关键字声明的函数相同,并以相同的方式调用。您可以通过以下方式测试:
In your example, there is no execution context surrounding foo
, so this
is undefined
. This is the same behavior as a function declared using the function
keyword at the same scope and called in the same way. You can test that with:
let foo = () => { return this; }
console.log(foo() === undefined);
从规格在14.2.16 :
任何对一个ArrowFunction中的参数,超级或此类的引用,都必须解析为在一个词汇封闭的环境中的绑定。通常,这将是一个立即包含功能的功能环境。
(强调我的)
有趣的是,当全局范围内存在该箭头功能时, BabelJS transpiler 简单地输出
Interestingly, when that arrow function is present in the global scope, the BabelJS transpiler simply outputs
"use strict";
var foo = function foo() {
return undefined;
};
好像是唯一正确的行为。阅读规范,它看起来不是很严格,但这似乎是正确的事情。
as if that were the only correct behavior. Reading the spec, it doesn't seem quite as strict, but this does seem like the right thing to do.
看起来你最终可以得到全局对象如果您使用没有模块的箭头来管理ES6代码。根据 10.2.1的规格:
It appears that you can end up with the global object as this if you manage to run ES6 code using arrows without modules. Per the spec at 10.2.1:
- 如果从包含使用严格指令的指令序言开始,全局代码是严格的模式代码(见
- 模块代码始终是严格的模式代码。
所以可能可以在非严格的上下文中获取ES6代码。如果发生这种情况,那么这个
将使用经典的回退,并设置为窗口
(在 9.2中的规范作为未定义的 [
So it is possible to get ES6 code in a non-strict context. If that happens, then this
will use the classical fallback and be set to window
(in the spec at 9.2 as an undefined [[ThisMode]]
).
在这个例子中,没有立即包含的函数,因此没有任何词汇范围可以接收,所以这个
最终没有定义。
In this example, there is no immediately enclosing function, thus no lexical scope to pick up, so this
ends up undefined.
在你的第二个例子中,在这个
没有区别:
In your second example, the capture on this
doesn't make a difference:
let o = {
foo: function() {
var self = this;
console.log(self);
},
bar() {
console.log(this);
}
};
var self
语句在函数内,所以它不会做任何事情。如果你要做:
The var self
statement is within the function, so it won't do anything. If you were to do:
let o = {
foo: function() {
var self = this;
return function() {
console.log(self);
}
}(),
bar() {
console.log(this);
}
};
那么它会有你期望的行为(大致),虽然 / code>仍然是未定义的(或全局对象),因为您不在要捕获的词汇环境中。
then it will have the behavior you expect (roughly), although this
will still be undefined (or the global object) because you're not within a lexical environment to be captured.
如果要使用
class Foo {
bar() {
let baz = () => { return this; }
}
}
然后 code>可以被折叠到
then bar
could be transpiled down to
function bar() {
var _this = this;
var baz = function baz() {
return _this;
};
}
这样做你想要的。这只能工作,因为有一个周围的环境被捕获。
which does what you want. That only works because there is a surrounding context to be captured.
这篇关于箭头功能 - 为什么会将全局对象打印到控制台?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!