0

我正在关注有关 javascript 闭包的文章

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

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定义吗?

4

1 回答 1

1

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

让我们一步一步来:

1.inner被声明为全局对象上的一个属性并且值被设置为undefined

1.5。创建outer函数,将全局范围作为其父范围

2.outer被调用。

outer3.为其作用域包括outerVar全局对象创建一个执行上下文。

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

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

…并且函数的父范围设置为outer.

5.完成的执行上下文outer(相关范围被删除?标记为 GC?)

…但不是垃圾收集,因为它仍然被引用为仍然存在的inner函数的父范围(不是垃圾)。

6.inner被调用。

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

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

8.不在outerVar范围内

…链。

于 2014-04-26T20:02:08.977 回答