这是我的代码:
function func(){
for(i=0; i < 5; i++){
alert('g');
}
}
for(i=0; i < 5; i++){
func();
alert('h');
}
我的期望是:gggghgggghgggghgggghggggh
但收到的只是ggggh
我发现那是因为JS中存在函数范围,而不是块范围。我想知道的是如何保持这种行为。我的意思是强制阻止范围。否则很容易制造出令人讨厌的错误 - 例如使用其他人写的函数或你自己编写的函数,但几个月前。
答案 0 :(得分:3)
这实际上与功能与块范围无关 - 它与隐式全局变量有关。
短篇小说:您在for
循环中意外创建全局变量 - 如果您使用for(var i=0;
而不是for(i=0;
,您将获得预期的结果。
稍长的版本:
alert("typeof i: " + typeof i);
// Alerts "typeof i: undefined"
function func() {
// References the *global* variable `i`
for(i=0; i < 5; i++){
alert('g');
}
}
// Creates a *global* variable `i` and sets it to 0
for(i=0; i < 5; i++) {
alert("i at start of iteration: " + i);
// Alerts "i at start of iteration: 0"
func();
// `func` has just altered *global* state - here's the proof
alert("i after call to func: " + i);
// Alerts "i at start of iteration: 5"
alert('h');
}
alert("typeof i: " + typeof i);
// Alerts "typeof i: number
// `i` is now in the global scope.
// Left as an exercise for the reader:
// try it again with `var i=0;` in both of the `for` loops.
答案 1 :(得分:2)
变量i的范围问题。
function func(){
for(var i=0; i < 5; i++){
alert('g');
}
}
for(var i=0; i < 5; i++){
func();
alert('h');
}
答案 2 :(得分:0)
尝试将i
声明为函数中的局部变量:
function func(){
var i;
for(i=0; i < 5; i++){
alert('g');
}
}
答案 3 :(得分:0)
正如其他答案中所述,您的代码无效,因为您没有使用var
声明i
变量,这会自动使其成为全局变量。所以不是功能与块范围问题。如果使用var
来声明变量,那么变量的范围将限制在声明为的相同函数中,包括在任何嵌套函数中,或全局如果不是在一个功能。
如果在嵌套函数中使用相同的变量名,则内部作用域中的变量名被称为“阴影”外部作用域;在这种情况下,内部函数无法访问该函数的外部函数的变量,因为使用该名称只会给它自己的变量。可以这么说。虽然您可以通过将全局变量视为window
对象的属性来访问全局变量。
“我想知道的是如何保留这样的行为。我的意思是强迫像块一样的东西。否则很容易做出非常讨厌的错误......”
嗯不,一旦你正确地开始使用var
,就不难避免这些错误。但是可以通过引入一个立即调用的匿名函数来强制阻止作用域:
(function() {
// variables created in this function are accessible
// only within this function
var x, y, z;
})();
console.log(typeof x); // "undefined" (x can't be seen from outside the function)
function(){}
周围的括号是必需的,因此该函数被解释为表达式而不是函数语句;最后的额外()
是使该函数表达式立即执行。此结构的一个常见用途是将整个脚本包含在其中,以便其中的变量或函数不会变为全局,因此不会与从其他JS包含文件加载的其他脚本进行交互。 (您可以在块中声明的块内共享伪全局变量。)
例如,如果你想将for
语句的主体变成带有范围的“块”,你可以这样做:
for (var i = 0; i < something; i++) {
(function() {
var x = i;
// do something with x
})();
}