箭头功能 - 为什么会将全局对象打印到控制台? [英] Arrow functions - why does this print the global object to the console?

查看:142
本文介绍了箭头功能 - 为什么会将全局对象打印到控制台?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么 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 -contextsrel =nofollow>执行上下文 。他们不会像常规方法那样改变这个

在你的例子中,没有 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆