【发布时间】:2015-12-09 18:57:14
【问题描述】:
这既是一个词法作用域的例子,也是一个确认我自己理解的问题。首先,考虑以下示例:
HTML:
<div id="testtxt"></div>
JS:
function fnTest(currentIdx, endIdx) {
$('#testtxt').html($('#testtxt').html() + 'Function Called ' + currentIdx + '<br />');
if (currentIdx < endIdx) {
setTimeout(function(){
fnTest(currentIdx + 1, endIdx);
}, 100);
}
}
fnTest(1, 10);
fnTest(11, 20);
输出:
Function Called 1
Function Called 11
Function Called 2
Function Called 12
Function Called 3
Function Called 13
Function Called 4
Function Called 14
Function Called 5
Function Called 15
Function Called 6
Function Called 16
Function Called 7
Function Called 17
Function Called 8
Function Called 18
Function Called 9
Function Called 19
Function Called 10
Function Called 20
当我第一次运行这个例子时,我担心 fnTest 会有一个全局闭包,因此 currentIdx 和 endIdx 会被 fnTest 的两个调用设置和访问。然而事实并非如此。
如果以下是解释它的好方法,请告诉我:
对 fnTest 的每次调用都会创建一个唯一的对象,变量 currentIdx 和 endIdx 存储在该对象的整个生命周期内以及该调用中的所有子例程(这称为闭包)。 setTimeout 调用从匿名函数创建一个新对象,该函数可以访问 fnTest 闭包,因此可以引用 currentIdx 和 endIdx,此对象/函数将在 100 毫秒延迟后执行。在执行时,匿名函数本身将通过调用 fnTest 创建一个新的 fnTest 闭包。此时,匿名函数引用的原始 fnTest 闭包可能会被处理掉。
请在必要时更正我的技术术语。
【问题讨论】:
-
“每次调用 fnTest 都会创建一个唯一的对象,其中存储了变量 currentIdx 和 endIdx”。这个“对象”被称为环境。每当您调用函数时,都会创建一个新环境。
标签: javascript closures lexical-scope