我的问题更多的是关于JavaScript的范围,而不是关闭。
我们来看下面的代码:
var f = function () {
var n = 0;
return function () {
return n++;
};
}();
console.log(f());
console.log(f());
以上代码输出:
0
1
从上面的代码中可以看出,f
(自我调用)返回一个函数,创建一个n
的闭包。
因此,它适用于匿名函数;因此,我用一个命名函数尝试了它:
var f2 = function () {
return n++;
};
var f = function () {
var n = 0;
return f2;
}();
console.log(f2()); // <= [n is not defined]
以上代码不起作用,错误为n is not defined
。我认为这是一个范围问题;但我无法确切地解释为什么;
为什么范围与匿名的内部函数相同但不适用于命名的外部函数?
另外,在第二个例子中,我是否创建了一个闭包?
答案 0 :(得分:4)
闭包是在第一个例子中创建的,因为匿名函数中的代码使用在匿名函数之外声明的局部变量。
在第二个示例中,函数n
中的f2
变量的范围已在声明函数时确定。创建具有相同名称的局部变量不会更改函数的含义,并且在另一个函数内使用该函数不会更改其范围。因此,该函数不使用局部变量。
答案 1 :(得分:2)
javascript中的范围是词汇http://en.wikipedia.org/wiki/Scope_%28programming%29#Static_scoping_.28also_known_as_lexical_scoping.29
答案 2 :(得分:2)
f2无法确定变量n的位置。
在第一个例子中,匿名函数在函数f内,在第二个 - 外部(f2而不是匿名)。因此,f2无法访问变量n,因为它位于另一个范围内且无法访问(不可见)。尝试将f2声明置于 f。
中答案 3 :(得分:0)
在你的第二个例子中,你没有创建一个闭包,你只是返回一个全局变量。 f2没有被关闭,因为它是在更一般的(在本例中为全局)范围中声明的,并且n
在更具体的范围内声明。可以在范围链“漏斗”下面关闭,而不是关闭,并且仅在所有相关实体在同一范围内定义时才有效。
答案 4 :(得分:0)
我们可以重写你的第二个例子,使其适用于命名函数:
var f = function() {
var n = 0;
var f2 = function() {
return n++;
};
return f2;
}();
console.log(f());
console.log(f());
这将输出0和1作为你的第一个例子。
正如其他答案所述,它不是关于被命名或匿名的函数,而是关于n和f2的范围。由于您在示例中在f之外声明了f2,因此它无法访问在f范围内声明的变量n。