var
-
- var声明的变量会挂载到全局上,因此会污染全局变量,并且没有作用域
// 浏览器的控制台测试
var a = 1
console.log(window.a) // 1
{
var b = 1
}
console.log(window.b) // 1
console.log(b) // 1
-
- 会导致变量提升,这里补充一下,函数也会导致变量提升
console.log(a) // undefined
var a = 1
-
- 可以被重复声明,后来声明的值会覆盖掉之前声明的值
var a = 1
var a = 2
var a = 3
console.log(a) // 3
let
-
- let声明的变量不会挂载到window上,会挂载到当前自己的作用域下
这里补充一下,常见的作用域:全局作用域和函数作用域
let a = 1
console.log(window.a) // undefined
{
let a = 1
}
console.log(a) // a is not defined
let a = 100;
{
console.log(a) // 报错,这里涉及到一个概念。即【暂时性死区”(temporal dead zone,简称 TDZ)】,其意思就是只要块级作用域内存在let命令,它所声明的变量就“绑定”(binding)这个区域,不再受外部的影响。
// 下方使用了let声明,即 a 已经被绑定在该作用域了,上面打印时候发现当前的作用域有 a,那么也就不会往外层作用域找,并且使用let声明的变量不会导致变量提升,因此就报错了。
let a = 1
}
-
- 不会导致变量提升
console.log(a) // 报错
let a = 1
-
- 不能重复声明
let a = 1
let a = 2
let a = 3
console.log(a) // Identifier 'a' has already been declared
const
const PI = {
r: "3.14"
}
PI.r = "3.15" //是可以实现的,也就是说使用const声明,只要保证其本身的地址值不变即可
for循环使用var或let引发的问题
先来看下这段代码:
for (var i = 0; i < 10; i++) {
setTimeout(function () {
console.log(i)
}, 1000);
}
解决方式一:使用匿名函数自调用,即相当于外面套了一层作用域
for (var i = 0; i < 10; i++) {
(function (i) {
setTimeout(function () {
console.log(i)
}, 1000);
})(i)
}
解决方式二 :使用let,这样就有属于自己的作用域,相当于自动帮助我们套了层作用域
for (let i = 0; i < 10; i++) {
setTimeout(function () {
console.log(i)
}, 1000);
}