JavaScript中的范围和闭包问题

时间:2009-11-23 10:29:21

标签: javascript function scope function-pointers closures

我的问题更多的是关于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。我认为这是一个范围问题;但我无法确切地解释为什么;

为什么范围与匿名的内部函数相同但不适用于命名的外部函数?

另外,在第二个例子中,我是否创建了一个闭包?

5 个答案:

答案 0 :(得分:4)

闭包是在第一个例子中创建的,因为匿名函数中的代码使用在匿名函数之外声明的局部变量。

在第二个示例中,函数n中的f2变量的范围已在声明函数时确定。创建具有相同名称的局部变量不会更改函数的含义,并且在另一个函数内使用该函数不会更改其范围。因此,该函数不使用局部变量。

答案 1 :(得分:2)

答案 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。