在这个例子中
var a = 1;
( function(x) {
function inner() {
alert(a);
alert(x);
alert(y);
}
var y = 3;
inner();
})(2);
何时创建function inner
?在外部匿名函数的执行时间或解析时间?
function inner
的范围链中有什么?
function inner
的执行上下文和范围链之间有什么区别?
感谢您提前启发我!
答案 0 :(得分:9)
inner
函数在Variable Instantiation进程执行匿名函数之前创建。
执行inner
时[[Scope]]
包含:
inner
的空变量对象(它是空的,因为里面没有变量/函数声明)x
,y
和inner
。a
和其他属性...... 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}}:“输入功能代码“。