JavaScript 中的作用域和闭包问题
我的问题更多的是关于 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 Define
。我认为这是一个范围界定问题;但我不明白到底为什么;
为什么作用域与匿名内部函数相同,但不适用于命名外部函数?
另外,在第二个示例中,我是否创建了一个闭包?
My question is really more about scope in JavaScript, rather then closures.
Let's take the following code:
var f = function () {
var n = 0;
return function () {
return n++;
};
}();
console.log(f());
console.log(f());
The above code outputs:
0
1
As you can see from the above code, f
(self-invoked) returns a function, creating a closure of n
.
So, it works with an anonymous function; thus, I then tried it with a named function:
var f2 = function () {
return n++;
};
var f = function () {
var n = 0;
return f2;
}();
console.log(f2()); // <= [n is not defined]
The above code doesn't work, with the error n is not defined
. I assume that this is a scoping issue; but I cannot figure why exactly;
Why is it that the scope is the same with an anonymous, inner function but does not work with a named, outer function?
Also, in the second example, am I creating a closure?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
第一个示例中创建了闭包,因为匿名函数中的代码使用了在匿名函数外部声明的局部变量。
在第二个示例中,函数
f2
中的n
变量的作用域在函数声明时就已确定。创建具有相同名称的局部变量不会改变该函数的含义,并且在另一个函数内使用该函数也不会改变它的作用域。因此,该函数不使用局部变量。The closure is created in the first example because the code in the anonymous function uses a local variable that is declared outside of the anonymous function.
In the second example the scope of the
n
variable in the functionf2
is already decided when the function is declared. Creating a local variable with the same name doesn't change the meaning of the function, and using the function inside another function doesn't change it's scope. Thus, the function doesn't use the local variable.javascript 中的作用域是词法的 http://en.wikipedia.org /wiki/Scope_%28programming%29#Static_scoping_.28also_known_as_lexical_scoping.29
scoping in javascript is lexical http://en.wikipedia.org/wiki/Scope_%28programming%29#Static_scoping_.28also_known_as_lexical_scoping.29
f2 无法确定应该在哪里获取变量 n。
在第一个示例中,匿名函数位于函数 f 内部,第二个示例中,匿名函数位于函数 f 外部(f2 而不是匿名函数)。因此,f2 无法访问变量 n,因为它在另一个作用域中并且无法访问(不可见)。尝试将 f2 声明放入 f 内。
There is no way for f2 to figure out where it should take variable n.
In first example anonymous function is inside function f, in second - outside (f2 instead of anonymous). So, f2 cannot access variable n, because it is in another scope and inaccessible (invisible). Try put f2 declaration inside f.
在第二个示例中,您没有创建闭包,而只是返回一个全局变量。 f2 没有被封闭,因为它是在更通用(在本例中为全局)范围内声明的,而
n
是在更具体的范围中声明的。关闭可以沿着作用域链“漏斗”向下进行,而不是向上,并且仅当所有相关实体都在同一作用域中定义时才有效。In your second example, you are not creating a closure, you are simply returning a global variable. f2 is not being closed over because it was declared in a more general (in this case, global) scope, and
n
is declared in a more specific scope. Closure is possible down the scope chain "funnel," not up, and is only effective when all related entities are defined in the same scope.我们可以重写您的第二个示例,使其与命名函数一起使用:
这将输出 0 和 1,就像您的第一个示例一样。
正如其他答案所述,这与函数的命名或匿名无关,而是与 n 和 f2 的范围有关。由于您在示例中在 f 之外声明了 f2,因此它无法访问在 f 范围内声明的变量 n。
We could rewrite your second example to make it work with a named function:
This would output, 0 and 1 as your first example did.
As the other answers have stated, its not about the function being named or anonymous, its about scope of n and f2. Since you declared f2 outside of f in your example, it had no access to the variable n declared inside the scope of f.