添加链接描述
JavaScript中var与let区别
ES6引入let关键字,在JS中var与let都是用来声明变量,var没有块级作用域,let有。let因为有了块级作用域,还会带其他的不同。
现在来具体举例说明下区别:
1、关于块级作用域
var a = 0;
{
var a = 1;
}
console.log(a); // 1
如果是let:
let a = 0;
{
let a = 1;
}
console.log(a); // 0
2、重定义同名变量
var b = 1;
var b = 2;
console.log(b); // 2
var b = 1;
{
var b = 2;
}
console.log(b); // 2
如果是let:
let b = 1;
let b = 2; // 报错。Identifier ‘b’ has already been declared
let b = 1;
{
let b = 2;
}
console.log(b); // 1
3、变量提升
var a = 1;
function foo() {
console.log(a); // undefined
var a = 2;
}
foo();
如果是let则抛异常。 a is not defined
4、全局对象属性
var a = 1;
console.log(window.a, a); // 1,1
如果是let:
let b = 1;
console.log(window.b, b); // undefined, 1
5、for(含for-of、for-in)循环中的不同,let会创建一个新的作用域
for (var i = 0; i < 3; i++) {
setTimeout(function() {
console.log(“setTimeout:”, i); // 3次3
});
}
如果是let:
for (let i = 0; i < 3; i++) {
setTimeout(function() {
console.log(“setTimeout:”, i); // 0,1,2
});
}
这是为什么?每次都会声明新的同名变量吗?那怎么递增和怎么影响到外部呢?
1.for(expression) 括号里面表达式是一个父级作用域
2.for循环的每个迭代都会创建一个新的{}作用域块,也就有了块级作用域。新的块是基于前一个执行环境所创建,在初始化时会把变量声明和最新赋值都带过来(thisIterationEnv.InitializeBinding (bn, lastValue))。因此变量会跟着递增,同时如果修改了{}块中的变量也会影响到表达式作用域中的同名变量。但如果在{}块内显式地声明了同名变量,则此时变量修改就不会影响到父级。
3.var允许重复声明覆盖外层同名的变量,let因为块级作用域所以不会覆盖父级同名的变量
循环就像以下:
var i = 1; i++;
{
var i = i; // i = 2
setTimeout(function() {
console.log(i); // 3
}, 0);
}
i = 3;
console.log(i); // 3
如果是let:
let i = 1; i++;
{
let i = 2;
setTimeout(function() {
console.log(i); // 2
}, 0);
}
i = 3;
console.log(i); // 3
再看一段代码:
for (let i = 0; i < 3; i++, console.log(“expression作用域:”, i)) {
setTimeout(function() {
console.log(“setTime function作用域:”, i);
});
let i = 10; // 删除这行试下
i++;
console.log(“for block作用域:”, i);
}
执行结果:
JavaScript中var与let区别