闭包
let var 闭包
一、产生作用域
ES5中,function可以产生作用域。
但在ES6中,不仅仅只有函数才能产生作用域。
1.var
var关键词,只能在函数中产生作用域。别的地方不会产生作用域。
首先来看 if 中的 var:
console.log( a );
if( false ){
var a = 10;
}
console.log( a );
运行结果如下:
解析顺序:
1.定义阶段:
var a;
2.执行阶段:
console.log( a );//undefined
if( false ){
a = 10;//判断为false,所以a = 10;无效
}
console.log( a );//undefined
得出结论 :var 不会把 if 看成一个作用域,所以var能被提前解析。
/*****************************************/
接下来,看 for 中的 var:
console.log(x);
for(;false;){
var y = 10;
}
console.log(x);
运行结果如下:
解析顺序:
1.定义阶段:
var a;//var不会把for看成一个作用域,所以var能被提前解析
2.执行阶段:
console.log( a );//undefined
for( ; false; ){
a = 10;//判断为false,所以a = 10;无效
}
console.log( a );//undefined
得出结论 :var 不会把 for 看成一个作用域,所以var能被提前解析。
除此之外,var 不会把 while 和 do…while 当做作用域,只会把函数当做一个作用域。
2.let
接下来看看let是否也是如此
for( let j=0;j<10;j++){
console.log(j);
}
console.log(j);
运行结果如下:
得到结论:
let 会把 for 的小括号当成一个单独的作用域,j不是全局变量,在全局作用域中不能使用局部作用域中的变量。
let 同样会把 if 和 while… 以及 do…while 的小括号当成一个单独的子作用域。在全局作用域中使用局部作用域变量直接报错。
那么,接下来来说说 let 的好处:
1.符合程序员的逻辑,只有先定义的变量才能使用,没有定义的变量不能提前使用,否则报错。
console.log(g);
let g = 10;//报错
2. 同一个作用域不可以 let 同一个变量,一个变量名在一个作用域下不能使用两次。
let b = 10;
let b = 20;//报错
3. let 不仅仅会把函数当成作用域,在 if 和 for 和 while 和 do…while… 中的 let 都会把他们当成是一个单独的作用域。
if(false){
let z = 3;
}
console.log(z);//报错
let n = 50