【问题标题】:How is this binding resolved for arrow functions?如何为箭头函数解析此绑定?
【发布时间】:2021-01-28 09:25:59
【问题描述】:

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

我知道函数可以通过闭包记住它的词法环境,但是在 chrome 开发工具中 this 不会出现在闭包中,而是出现在本地范围内。为什么会这样?

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

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

【问题讨论】:

    标签: javascript node.js this


    【解决方案1】:

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

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

    14.2 Arrow Function Definitions 部分涉及主题,14.2.17 Runtime Semantics: Evaluation 附有以下注释:

    ArrowFunction 没有为 argumentssuperthisnew 定义本地绑定.targetArrowFunction中对 argumentssuperthisnew.target 的任何引用> 必须解析为词法封闭环境中的绑定。通常,这将是直接封闭函数的函数环境。 [...]

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

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

    Internal Slot Type Description
    [[ThisMode]] (lexical, strict, global) Defines how this references are interpreted within the formal parameters and code body of the function. lexical means that this refers to the this value of a lexically enclosing function. strict means that the this value is used exactly as provided by an invocation of the function. global means that a this value of undefined is interpreted as a reference to the global object.

    * “几个不同的地方”只是关于将[[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();

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

    【讨论】:

      猜你喜欢
      • 2016-03-24
      • 2022-12-06
      • 2018-11-10
      • 1970-01-01
      • 1970-01-01
      • 2023-03-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多