JavaScript内部函数范围链?

时间:2010-05-18 14:49:27

标签: javascript scope

在这个例子中

var a = 1;
( function(x) {   
   function inner() {
      alert(a);
      alert(x);
      alert(y); 
   }
   var y = 3;
   inner();
})(2);

何时创建function inner?在外部匿名函数的执行时间或解析时间?

function inner的范围链中有什么?

function inner的执行上下文和范围链之间有什么区别?

感谢您提前启发我!

2 个答案:

答案 0 :(得分:9)

inner函数在Variable Instantiation进程执行匿名函数之前创建。

执行inner[[Scope]]包含:

  1. inner的空变量对象(它是空的,因为里面没有变量/函数声明)
  2. 匿名函数的变量对象,其中包含xyinner
  3. 全局对象,包含a和其他属性......
  4.     Global (3)          Anonymous VO (2)       inner VO (1)
       ________              ________              ________
      | a = 1  | <--------- | x = 2  | < -------- |        |
      | ...    |            | y = 3  |             ¯¯¯¯¯¯¯¯ 
       ¯¯¯¯¯¯¯¯             | inner  |
                             ¯¯¯¯¯¯¯¯ 
    

    修改:澄清您的第二个问题:

      

    函数inner的执行上下文和范围链之间有什么区别?

    是两个不同的概念,执行上下文是在一段代码(执行can be全局代码,函数代码或eval代码)之前创建的。

    我认为使用您的代码可能更容易解释:

    var a = 1;
    (function(x) {        // Step 1
       function inner() {
          alert(a);
          alert(x);
          alert(y); 
       }
       var y = 3;
       inner();           // Step 3
    })(2);                // Step 2
    

    步骤1 中,匿名函数为created,当前作用域(仅包含全局对象)此时存储在函数[[Scope]]属性中。

    步骤2 中,执行此匿名函数,创建一个新的执行上下文(function code execution context),此时创建一​​个新的词法环境(变量对象)创建此函数),所有函数参数标识符(在本例中仅为x),函数声明的标识符(inner)和变量声明的标识符(y)绑定为非此新变量对象的可删除属性(这是新的词法范围)。

    步骤3 中执行inner函数,这会创建一个新的执行上下文,另一个变量对象被注入到作用域链中,但在这种情况下,因为没有在内部声明任何内容inner并且它没有任何形式参数,它只是一个空对象。

    另见this回答,第一部分我谈的是with陈述,但第二部分是关于功能的。

答案 1 :(得分:7)

  

什么时候创建函数内部?在外部匿名函数的执行时间或解析时间?

每次执行外部函数时都会创建一个。

  

函数inner的范围链是什么?

执行它时,该执行会获得一个变量对象(从技术上讲,规范称之为“变量环境的绑定对象”);由为创建inner的外部函数调用创建的变量对象支持;这是由全局变量对象支持的。所以:

+------------------------------+
| global variable obj          |
+------------------------------+
    ^
    |
   +-----------------------------+
   | variable obj for outer call |
   +-----------------------------+
       ^
       |
      +-----------------------------+
      | variable obj for inner call |
      +-----------------------------+
  

函数inner的执行上下文是什么?

每个函数调用都有自己的执行上下文。我不太清楚我明白这里有什么问题。

你可以在the spec的第10部分,尤其是section 10.4.3中阅读所有这些内容(如果你愿意趟过粗俗的散文),那就是<{3}}:“输入功能代码“