2

在以下代码中:

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似乎暗示回调是从测试函数内部调用的。

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

我想我的问题是:

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

4

3 回答 3

1

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

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

说明:回调在词法上存在于函数 test()中,因此它总是会尝试在自身内部(如果存在)找到this的值,否则它将在外部环境中看到它的值(在这种情况下是函数 test )

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

引擎如何单独跟踪执行上下文的范围?

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

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

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

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

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

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

于 2016-07-23T07:42:16.957 回答
1

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

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

于 2016-07-23T09:44:37.380 回答
1

在 javascript 中调用函数时,会将上下文传递给它。

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

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

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

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

于 2016-07-23T09:51:44.827 回答