var声明变量和作用域的一小点理解

在let出现之前,一直使用var来声明变量,那个时候面试常问的一些问题诸如变量提升,for循环的坏处之类的。
现在虽然有了更可靠的let,因为还有老的代码存在,所以这里也记录下var所存在的问题。

变量污染的问题

for(var i = 0;i<10;i++){}
console.log(i); // 10

if(true) {
  var b = 1;
}
console.log(b); // 1

像上面的代码,在for,if,或者switch等操作中,我们无意间会创建出某些变量,造成变量污染,这并不是我们理想的样子。

使用let来优化:

for(let i = 0;i<10;i++){}
console.log(i); // a is not defined

if(true) {
  let b = 1;
}
console.log(b); // b is not defined

作用域考察问题

以前的一个经典的面试题,我被问到过好几次:
如何在不修改定时器的情况下打印出0-9?

for(var i = 0; i < 10; i++){
  setTimeout(function(){
    console.log(i);
  }, 0)
}
// 这里是打印出10个10
  • 想要0-9只需要把var改成let就可以了,var创建的是全局的变量,定时器中拿到的i已经是for循环叠加之后的i了,所以得到了10。let则是当前作用域下的变量,定时器中拿到的i是每次循环的i,所以得到了0-9。

  • 创建一个封闭的作用域区间

for(var i = 0; i < 10; i++){
  (function(a){
    setTimeout(function(){
      console.log(a); // 得到0-9
    }, 0)
  })(i);
};

通过自执行函数的封闭区间来实现类似let的效果,让i仅在当前作用域下生效。

你可能感兴趣的:(var声明变量和作用域的一小点理解)