首页 > 解决方案 > 如何为箭头函数解析此绑定?

问题描述

在箭头函数中没有this绑定。因此,箭头函数在词法上解析了这个引用。如果我们在与定义函数的范围不同的范围内执行函数,它会记住这个引用。这种行为是否由于关闭而发生?

我知道该函数可以通过闭包记住其词法环境,但在 chrome 开发人员工具中,不会出现在闭包中,而是出现在本地范围内。为什么会发生这种情况?

function outerScope(outerVar){
    let innerFun = () =>{
    console.log(outerVar);
    console.log(this);
}
return innerFun;
}

let innerFun = outerScope.call({test: "testing this reference"},"outerVar");
innerFun();

在此处输入图像描述

标签: javascriptnode.jsthis

解决方案


这种行为是否由于关闭而发生?

您的陈述暗示这是其他机制的副作用。它故意成为规范的一部分。

14.2 节箭头函数定义处理主题和14.2.17 运行时语义:评估附有以下注释:

ArrowFunction不为argumentssuperthisnew.target定义本地绑定。在 ArrowFunction 中对 arguments 、 super 、 this 或 new.target 的任何引用必须解析词法封闭环境中的绑定。通常,这将是直接封闭函数的函数环境。[...]

(注释的其余部分涉及调用super和方法)

注释不是定义而是作为提醒。原因在规范中分散在几个不同的地方*,但最相关的是函数有一个特定的内部槽,第9.2 节 ECMAScript 函数对象定义为:

内部插槽 类型 描述
[[此模式]] (词汇​​,严格,全局) 定义如何在函数的形式参数和代码主体中解释引用。lexical表示this指的是一个词法封闭函数的this值。strict意味着this值完全按照函数调用所提供的方式使用。global意味着undefined的this值被解释为对全局对象的引用。

*“几个不同的地方”只是将[[ThisMode]]内部插槽设置为的箭头功能lexical

这就是箭头函数this在其定义位置使用词法绑定而不是闭包产生影响的原因。

还可能值得注意的是,在许多情况下,“闭包”最终并不是一个非常有用的术语——每个函数定义都形成一个闭包。很多时候,这种机制并没有什么特别之处,所以不值得讨论。只有当一个函数使用在它之外定义的变量时,它才是有趣的(并且值得一提)。它“关闭”的那些:

const a = 42; //<--+----+
//                 |    |
function f() {//   |    |
    return a; // --+    |
}//                     |
//                      |
function g() { } // ----+

两者fg都可以访问变量a,因为它们是在相同的环境中定义的——它们的创建机制不会根据它们的主体而改变。这很容易验证(需要打开浏览器开发者工具才能触发断点):

const a = 42;

function f() {
    return a;
}

function g() { debugger; }

g();

运行上述代码片段的 Firefox 开发者控制台的屏幕截图。 执行在函数 g 的主体内停止,外部变量的值可以在 Scopes 部分中找到。

话虽如此,g在绝大多数情况下根本不值得讨论,因为关闭机制没有影响。


推荐阅读