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

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

本文关键字:函数 回调 访问 变量 作用域 上下文 为什么 执行 全局 Javascript      更新时间:2023-09-26

在以下代码中:

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变量。

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

我读到执行和范围是不一样的。在本文中: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似乎意味着回调是从测试函数中调用的。

因为在我看来,无论在哪里调用回调函数,它的作用域仍然是要测试的。

我想我的问题是:

在考虑范围和执行上下文时,如何根据定义和调用来处理回调函数?

如何根据定义处理回调函数,然后在考虑范围和执行上下文时调用?

函数范围基于它在词汇环境中的物理位置

解释:回调函数测试()中存在,因此它总是试图在自己内部(如果存在)找到this的值,否则它将在外部环境中看到它的值(在这种情况下是功能测试

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

引擎如何将范围与执行分开跟踪上下文

词汇环境:在您编写的代码中,某个东西的物理位置。

执行上下文:用于帮助管理正在运行的代码的包装器。

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

无论何时创建执行上下文,我们都有三件事可用:

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

因此,根据当前运行的执行上下文,这些内容将因其在代码中的物理或词汇位置而异。例如,cb的外部环境是function test()

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

传递给logCb的函数是在test内部创建的,因此它可以访问test的作用域。

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

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

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

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

  3. 如果以上两个都没有通过全局对象即窗口

因为闭包。闭包是词汇环境的功能。词汇环境是指局部变量的集合及其对其父变量的引用。在您的代码中,您在测试函数中定义了回调函数,回调函数将创建一个带有词法环境的闭包,该环境包含对其父变量的引用。通过使用这个闭包,函数仍然可以访问变量x.