【问题标题】:Lifetime of Nested Execution Contexts嵌套执行上下文的生命周期
【发布时间】:2014-04-26 19:43:02
【问题描述】:

我正在关注article on javascript closures

在尝试了解执行上下文的细节时,我遇到了一个令我惊讶的结果。

var globalVar = 'g';
var inner;
var outer = function() {
  var outerVar = 'o';
  inner = function() {
    var innerVar = 'i';
    console.log(innerVar, outerVar, globalVar);
  }
}

outer()
inner() // Q: What does this log out?

http://jsfiddle.net/6zvsh/

这实际上输出i o g

我希望看到i undefined g

这是我对这个过程的理解。我想了解我的错误:

  1. inner 被声明为全局对象的属性,并且值设置为 undefined
  2. outer 被调用。
  3. outer 创建一个执行上下文,其作用域链包括outerVar 和全局对象。
  4. 为全局对象上的inner 属性值分配了对函数定义的引用。
  5. outer 的执行上下文完成。 (相关范围被删除?标记为 GC?)
  6. inner 被调用。
  7. 创建了一个执行上下文,其作用域链包括innerVar 和全局对象。
  8. 范围内找不到outerVar

谁能解释一下为什么定义outerVar

【问题讨论】:

  • 你刚刚发现了闭包! How do JavaScript closures work?
  • 这也可能是答案:stackoverflow.com/a/11148475/111243
  • 该评论可能比必要的更讨人喜欢,@Bergi。我认为这是一个关于调用和声明之间的一些我不理解的细微差别的问题,而不是需要一个总体概述。我正在阅读一些不同的概述,都一样:)

标签: javascript scope executioncontext


【解决方案1】:

当一个函数被创建时,它引用它周围的执行上下文作为作用域,为它创建一个closure

让我们一步一步来:

1。 inner 被声明为全局对象的属性,值设置为undefined

1.5。 outer 函数被创建,将全局作用域作为其父作用域

2。 outer 被调用。

3。为outer 创建一个执行上下文,其范围chain 包括outerVar 和全局对象。

...因为新执行上下文的链链接引用了outer 的父作用域,即(在1.5 中分配的)全局作用域。 outerVar 是这个新执行上下文中的一个变量。

4。全局对象上的inner 属性的值被分配了对函数定义的引用。

…并且函数的父作用域设置为outer的执行上下文。

5。 outer 的执行上下文完成。 (相关作用域被移除?标记为GC?)

...但没有被垃圾回收,因为它仍然被引用为 inner 函数的父作用域,该函数仍然存在(不是垃圾)。

6。 inner 被调用。

7。创建一个执行上下文,其范围 chain 包括 innerVar 和全局对象。

新的执行上下文有一个作用域链链接到inners 父上下文,这是上面为outer 调用创建的执行上下文(它具有到全局作用域的链链接)。 innerVar 是这个新执行上下文中的一个变量。

8。 outerVar 不在范围内找到

…链。

【讨论】:

  • 太棒了。我认为我错过的关键是将范围分配给函数对象的时间。我总结如下: 问:为什么它可以访问outerVar? A: 因为在运行outer 时,会为inner 创建一个函数对象,其[[scope]] 被分配了outer 的执行上下文的值。外部的执行上下文的范围是一个包含激活/变量对象(参数,outerVar)和全局对象的链。因为 GC 可以看到全局 inner 属性对 external 的 executionContext 范围的引用,所以该范围被维护。
  • 是的,完全正确。只是我没有专注于使用正确的术语(没有时间引用relevant spec section),如果我混淆了“范围”和“执行上下文”这两个术语,请原谅。
猜你喜欢
  • 1970-01-01
  • 2013-07-17
  • 2014-11-28
  • 2015-05-06
  • 2017-11-08
  • 1970-01-01
  • 1970-01-01
  • 2016-01-31
  • 1970-01-01
相关资源
最近更新 更多