var和let的区别

作用域

var是函数作用域,而let是块作用域。

在ES6之前,我们都是用var来声明变量,而且JS只有函数作用域和全局作用域,没有块级作用域,所以{}限定不了var声明变量的访问范围。

{ 
  var i = 9;
} 
console.log(i);  // 9
var j=0;
{
    console.log(j);//0
}

ES6新增的let,可以声明块级作用域的变量。

{ 
    let i = 9;
    console.log(i) // 9
} 
console.log(i);  // Uncaught ReferenceError: i is not defined

变量提升

​ let必须先声明,在使用;而var先使用后声明也行。只不过直接使用但没有定义的时候,其值是undefined。var有一个变量提升的过程,当整个函数作用域被创建的时候,实际上var定义的变量都会被创建,并且如果此时没有初始化的话,则默认为初始化一个undefined

// var 的情况
console.log(a); // 输出undefined
var a = 100;
    
// let 的情况
console.log(b); // 报错ReferenceError
let b = 200;

上面代码变量a用var声明,会发生变量提升,因没有值,所以会输出undefined。变量b用let声明的则不会发生变量提升。

重复声明

var可以允许重复声明相同的变量,后者会覆盖前者;

let不允许在相同作用域内,重复声明同一个变量。

// 报错
function func() {
  let a = 10;
  var a = 1;
}

// 报错
// Uncaught SyntaxError: Identifier 'a' has already been declared
function func() {
  let a = 10;
  let a = 1;
}

因此,不能在函数内部重新声明参数。

function func(a) {
  let a; // 报错
}

function func(a) {
  {
    let a; // 不报错
  }
}

常见习题

for (var i = 0; i <10; i++) {  
    setTimeout(function() {  // 同步注册回调函数到 异步的 宏任务队列。
         console.log(i);        // 执行此代码时,同步代码for循环已经执行完成
      }, 0);
}
 // 输出结果
//10   共10个 

如果把 var改成 let声明:

// i虽然在全局作用域声明,但是在for循环体局部作用域中使用的时候,变量会被固定,不受外界干扰。
for (let i = 0; i < 10; i++) { 
  setTimeout(function() {
    console.log(i);    //  i 是循环体内局部作用域,不受外界影响。
  }, 0);
}
// 输出结果:
0  1  2  3  4  5  6  7  8 9

总结

总的来说,let和var的区别主要有三点:作用域的不同、是否存在变量提升、能否重复声明

posted @ 2021-10-01 20:59  幻飞  阅读(653)  评论(0)    收藏  举报