//Lets start with a basic Javascript snippet
function generateCash() {
var denomination = [];
for (var i = 10; i < 40; i += 10) {
denomination.push(i);
}
return denomination;
}
这在Javascript基本功能语句返回的[10,20,30]
//--Lets go a step further
function generateCash() {
var denomination = [];
for (var i = 10; i < 40; i += 10) {
denomination.push(console.log(i));
}
return denomination;
}
阵列这将打印10,20,30 sequentialy作为循环迭代,但会返回一个[undefined,undefined,undefined]的数组,主要原因是我们没有推送i的实际值,我们只是将其打印出来,因此在每次迭代时javascript引擎都会将其设置为undefined。
//--Lets dive into closures
function generateCash() {
var denomination = [];
for (var i = 10; i < 40; i += 10) {
denomination.push(function() {
console.log(i)
});
}
return denomination;
}
var dn = generateCash();
console.log(dn[0]());
console.log(dn[1]());
console.log(dn[2]());
这有点棘手,你期望输出是什么,它会是[10,20,30]?答案是否定的,让我们看看这是怎么发生的。首先创建一个全局执行上下文,当我们创建dn时,我们也有generatecash()函数。现在我们看到,随着for循环的迭代,它创建了三个匿名函数对象,可能会想到push函数中的console.log也被触发了,但事实上并非如此。我们调用了generateCash(),所以push函数只是创建了三个匿名函数对象,它不会触发函数。在迭代结束时,当前的本地上下文从执行堆栈中弹出,并且它离开i:40和arr:[functionobj0(),functionob1(),functionobj2()]的状态。
所以当我们开始执行最后三条语句时,它们都输出40,因为它无法从当前范围中获取i的值,所以它会上升到范围链并发现i的值有被设置为40.他们之所以会激发40的原因是因为dn的每个组件都在同一个执行上下文中,并且他们都无法在当前范围中找到i的值,所以它们会上升到范围链并发现我设置为40,并分别输出它
[“var functionName = function(){}”与“function functionName(){}”in Javascript]中的可能重复(http://stackoverflow.com/questions/336859/var-functionname-function-vs-function-functionname-in-javascript) – BrunoLM 2010-10-11 01:56:35
@BrunoLM:我认为这是一个不同的问题。 – Thilo 2010-10-11 02:01:54
@Thilo:同样的答案适用。 – BrunoLM 2010-10-11 02:02:19