前提:JavaScript没有块级作用域的概念,如下面的例子:在js中,变量i是定义在outputNumbers()的活动对象中的,因此可在函数内部随处访问它,即使像下面例子错误地重新声明同一个变量,也不会改变i的值;但在Java、C++等语言中,变量i只在for循环的语句块中有定义,循环结束则i被销毁。
function outputNumbers(count){
for(var i=0;i<count;i++){
}
var i;//重新声明变量
console.log(i);//输出count的值,i在for循环里累加到count
}
解决:用匿名函数可以模仿块级作用域(私有作用域),语法如下;
下面代码定义并立即调用一个匿名函数;将函数声明包含在一对圆括号中,表示它实际上是一个函数表达式;而后面的另一对圆括号会立即调用这个函数。
(function(){
//这里是块级作用域
})();
结合for循环例子,利用匿名函数将变量i放在模仿块级作用域中用;在匿名函数中定义的任何变量,都会在执行结束时销毁;因此变量i只能在循环中使用,使用后即被销毁。
function outputNumbers(count){
(function(){
for(var i=0;i<count;i++){
console.log(i);
}
})();
console.log(i);//报错“i is not defined”
}
好处:这种做法可以减少闭包占用的内存问题,因为没有指向匿名函数的引用。只要函数执行完毕,就可以立即销毁其作用域链了。