1.var声明的作用域
function test() {
var message = "hi";
}
test();
console.log(message);
var是函数作用域,在函数中声明了var,整个函数内都是有效的,比如说在for循环内定义的一个var变量,实际上其在for循环以外也是可以访问的。
2.var声明提升
function foo() {
console.log(age);
var age = 26;
}
foo();
以上代码等同于
function foo() {
var age;
console.log(age);
age = 26;
}
foo();
所谓提升,就是把所有变量声明都拉到函数作用域顶部,所以不会报错。
3. let 声明的作用域
let是块作用域。let由于是块作用域,所以如果在块作用域内定义的变量,比如说在for循环内,在其外面是不可被访问的,所以for循环推荐用let。
function test() {
for (var t = 0; t < 3; t++) {
console.log(t);
}
console.log(t);
}
test();
如果把以上代码的 var 换成 let,那么最后一个 console.log(t) 就会报错。
而 let 也不能重用同一变量名,这也会报错。
在不同的块中,let会被解释成不同的变量。
function test() {
let t = 0;
for (let t = 0; t < 3; t++) {
console.log(t);
}
console.log(t);
}
test();
以上代码会输出 0 1 2 0 的4个数字,最后一个数字说明此let非彼let。
4.let 暂时性死区
let 与 var 另一个区别在于,let 不会在作用域中被提升,也就是不会被拉到函数顶部。
console.log(age);
var age;
console.log(test);
let test;
第一个没报错,第二个报错了。这说明let没提升,而var提升了!
5. const 关键字
const 定义的变量不可修改,而且必须初始化,不能用null 占位; 在相同作用域里,不可以重复声明同一个变量; 声明的变量不会存在变量提升; 声明的是复杂类型数据,可以修改属性;
var a1
console.log(a1) // undefined
console.log()
// 在相同作用域里
{
var b1 = 1
var b1 = 2 // 可以重复声明变量
console.log(b1) // 2
// let b2 = 21
// let b2 = 22 // 报错
// const b3 = 31
// const b3 = 32 // 报错
}
console.log(b1) // 2
// console.log(a2)// “暂时性死区”,在代码块内,使用let命令声明变量(或者const声明常量)之前,
let a2
console.log(a2)// undefined
// console.log(a3)// “暂时性死区”,在代码块内,使用let命令声明变量(或者const声明常量)之前,
const a3 = 31
// const a3
// console.log(a3)// 初始化必须声明,不然会报错