ES5中是没有块级作用域,只有全局作用域和函数作用域的概念。常见的错误如下:

var obj = {};
for(var i = 0; i < 3; i++){
   var p = i;
   obj[i] = function(){
      console.log(p);
   }
}
obj[0]();//2
obj[1]();//2
obj[2]();//2

所有输出结果都是2。这种写法把i,p是写在for中,但for没有作用域,所以i和p实际定义在全局作用域之下的,在循环结束后,i值为3,p值为2。需要用函数作用域将变量变为私有化即可,如:

var obj = {};
for(var i = 0; i < 3; i++){
   (function (i){
      var p = i;
      obj[i] = function(){
         console.log(p);
      }
   })(i);
}
obj[0]();//0
obj[1]();//1
obj[2]();//2

ES6中的块级作用域有两个let和const;

let和var都是声明变量,但是let有块级作用域,并且是即死区域(不会变量提升);用let写下上面的代码:

var obj = {};
for(let i = 0; i < 3; i++){
   obj[i] = function(){
      console.log(i);
   }
}
obj[0]();
obj[1]();
obj[2]();

const和let差不多,只是const用来声明恒定变量,所以必须声明时就要赋值,否则报错。