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

时间:2016-07-23 07:35:30

标签: javascript scope executioncontext

在以下代码中:

log.SetFlags(log.LstdFlags|log.Llongfile)

x用于测试,这是定义回调函数的地方。我希望行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() 抛出错误,因为logCb()函数无法访问x变量。

但事实并非如此。为什么?似乎回调中的引用是在赋值期间创建的,而不是在执行期间创建的 - 如果您考虑提升,我认为是有意义的 - 即在编译期间,回调函数被提升到'test'的顶部然后赋值发生在test的中范围?

我已经读过执行与范围不同。在本文中:http://ryanmorr.com/understanding-scope-and-context-in-javascript/,这句话cb()似乎意味着从测试函数中调用回调。

因为在我看来,无论在何处调用回调函数,它仍然可以用于测试。

我认为我的问题是:

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

3 个答案:

答案 0 :(得分:1)

  

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

功能范围基于它在词汇环境中的实际存在位置

说明:回调在词典中存在于功能测试()中,因此它总是会尝试找到的值在其内部(如果存在)否则它将在外部环境中看到它的值(在这种情况下功能测试

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

  

引擎如何分别跟踪范围到执行   上下文

词汇环境:在您编写的代码中物理上存在的东西。

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

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

每当创建执行上下文时,我们都有三件事可供我们使用:

  1. 全局对象(窗口):全局范围内的任何变量或函数都链接到窗口对象
  2. '这'
  3. 外部环境
  4. 因此,根据当前正在运行的执行上下文,这些内容将根据代码中物理上或词汇上的位置而有所不同。例如,function test()的外部环境是compile 'org.greenrobot:eventbus:3.0.0' //Some Class public class MessageEvent { public final String message; public MessageEvent(String message) { this.message = message; } } //In Activity @Override public void onStart() { super.onStart(); EventBus.getDefault().register(this); } @Override public void onStop() { EventBus.getDefault().unregister(this); super.onStop(); } //From Broadcast Receiver //Add this in the Connected and Disconnected methods EventBus.getDefault().post(new MessageEvent("Hello everyone!"));

答案 1 :(得分:1)

范围取决于函数创建的位置,而不是调用它的位置。

您传递给logCb的功能是在test内创建的,因此可以访问test的范围。

答案 2 :(得分:1)

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

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

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

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

  3. 如果上述2都不通过全局对象即窗口