Javascript: 为什么具有全局执行上下文的回调函数可以访问作用域变量?

Javascript: why do callback functions with global execution context have access to scoped variables?

在下面的代码中:

function test() {
    var x = 5 // scoped to test function
    console.log(this); // global object
    logCb(function(){
        console.log(this); // global object
        console.log(x);
    })
}

function logCb (cb) {
    console.log(this); // global object
    cb() // This still seems to execute within the test function scope? why...
}

test()

x 用于测试,这是定义回调函数的地方。我本以为 cb() 行会抛出错误,因为 logCb() 函数无法访问 x 变量。

然而事实并非如此。为什么?回调中的引用似乎是在赋值期间创建的,而不是在执行期间创建的——如果你考虑提升,我想这是有道理的——即在编译期间,回调函数是否被提升到 'test' 的顶部,然后赋值发生在测试范围内?

我读到执行与作用域不同。在这篇文章中:http://ryanmorr.com/understanding-scope-and-context-in-javascript/,这句话scope pertains to the variable access of a function when it is invoked and is unique to each invocation似乎暗示回调是从测试函数内部调用的。

因为在我看来,无论在哪里调用回调函数,它仍然会被限定为测试范围。

我想我的问题是:

在考虑作用域和执行上下文时,回调函数是如何定义和调用的?

How is the callback function handled in terms of definition and then invocation when thinking about scope and execution context?

函数作用域基于它在词法环境中的物理位置

解释:回调函数test()中按词法出现,所以它总是会尝试找到[的值=30=]this 在自身内部(如果存在)否则它将在外部环境中看到它的值(在这种情况下是 function test

测试函数LogCb函数将遵循相同的做法。在这种情况下,外部环境将是 global

how does the engine keep track of scope separately to execution context?

词法环境:您编写的代码中物理位置。

执行上下文: 帮助管理 运行.

代码的包装器

现在你的代码中有很多词法环境。当前 运行 是哪一个是通过执行上下文管理的。它可以包含超出您在代码中编写的内容。

无论何时创建执行上下文,我们都可以使用三样东西:

  1. 全局对象(window):全局范围内的任何变量或函数链接到window对象
  2. 'this'
  3. 外部环境

因此,根据当前 运行 的执行上下文,这些内容会根据它在代码中的物理位置或词法位置而有所不同。例如 cb 的外部环境是 function test()

作用域由创建函数的位置决定,而不是由调用它的位置决定。

您传递给 logCb 的函数是在 test 中创建的,因此它可以访问 test 的范围。

在 javascript 中调用函数时,会向其传递一个上下文。

上下文可以是以下方式之一

  1. 使用 new 创建一个临时对象,并将其作为上下文传递给函数

  2. 通过对象 a.getValue() 调用函数。 getValue 获取上下文 a

  3. 如果上面2个的none传递全局对象即window