var 声明
-
var 声明函数作用域
等于在局部函数定义了一个变量,就意味着该变量在局部函数退出时销毁。
function test() {
// 这里面是函数作用域
}
-
var 声明提前
声明的变量会自动提升到函数作用域顶部
function test() {
console.log(a);
var a = 1;
}
test();
// test函数执行过程
function test() {
// 先声明提前
var a;
console.log(a);
a = 1;
}
// 所以输出为;undefined;
let 声明
-
与 var 的区别是,let 的范围是块作用域,而 var 的范围是函数作用域
if 块,var 声明了之后,能在 if 块外部使用,而 let ,仅限于该块内部。
块作用域是函数作用域的子集。
if (true) {
let a = 1;
var b = 1;
}
console.log(b); // 1;
console.log(a); // ReferenceError a 未定义;
- 不能重复声明,但可以重复赋值
let a = 1;
a = 2;
let a = 3; // SyntaxError a 重复定义;
-
暂时性死区
不会声明提升,在声明之前使用时,会报错,ReferenceError
console.log(a);
let a = 1; // ReferenceError a 未定义
-
全局声明
不会称为window对象的属性
var a = 1;
console.log(window.a); // 1
let b = 1;
console.log(window.b); // ReferenceError b 未定义
-
条件声明
声明只在该块内有效,这个在上面的 if 块里面看到了。
-
解决 for 循环中的 var 声明问题;
for (var a = 0; a < 5; a++) {
setTimeout(function() {
console.log(a)
}, 0)
}
/*
上面会输出5个5;
为什么会这样呢;
首先里面是 setTimeout,里面定义的函数不会立即执行,会放到一个等待的栈里面,等 setTimeout 的时间跑完,才会放到待执行的栈中,等正在执行的栈里面的任务全部跑完,才会去待执行的栈里面拿任务,这一轮下来,你看看,a 已经被赋值了什么,已经变成5了,因为 var 的作用域是函数作用域,所以 a 被 for 循环里面重复赋值。
那我们用 let 试试看,因为 let 的作用域是块作用域,所以 a 的值没有被重复赋值,a还是原来那个值;所以我们输出一下;
*/
for (let a = 0; a < 5; a++) {
setTimeout(function() {
console.log(a)
}, 0)
}
// 0,1,2,3,4
const 声明
声明变量时必须同时初始化变量。不能修改值。
var , let , const 的区别
var:重复性声明,声明提前,函数作用域
let: 块作用域,只能声明一次,暂时性死区,不会声明提前
const:块作用域,声明的同时要赋值,不能改变值