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的区别主要有三点:作用域的不同、是否存在变量提升、能否重复声明

浙公网安备 33010602011771号