1.var
- var 声明的变量属于函数作用域
- var 声明的变量存在提升(hoisting)
- var 变量可以重复声明
1.1 var关键字
定义变量可以使用var,后面跟变量名,如var a = 1;这样就是将1赋值给a;当然a可以保存任何类型的值。我们还可以改变a保存的值,也可以改变值的类型,如var a=1;==> var a ="hi";
1.2 var作用域
1.如果使用关键字 var 声明一个变量,那么这个变量就属于当前的函数作用域,如果声明是发生在任何函数外的顶层声明,那么这个变量就属于全局作用域。
var a = 123; //此处声明的变量a为全局变量
function num() {
var a = 321; // 此处声明的变量a为函数num的局部变量
console.log(a); // 321
}
num();
console.log(a); // 123
2.提升是指:无论 var 出现在一个作用域的哪个位置,这个声明都属于当前的整个作用域,在其中到处都可以访问到。注意:只有变量声明才会提升,对变量赋值并不会提升
var a
console.log(a) // undefined
a = 123
3.如果在声明变量时,省略 var 的话,该变量就会变成全局变量,如全局作用域中存在该变量,就会更新其值
var a=123;
function num() {
a = 321; // 此处的变量a是全局变量
console.log(a); // 321
}
num();
console.log(a); // 321
2.let
- let 声明的变量具有块作用域(局部变量)的特征。
- let 在同一个块级作用域(局部变量),不能重复声明变量。
- let 声明的变量不存在变量提升,存在暂时性死区(TDZ)。
- let 不影响作用域链。
2.1 创建变量代码示例
// let关键字使用示例:
let a // 单个声明
let b,c,d // 批量声明
let e = 100 // 单个声明并赋值
let f = 521, g = 'hello', i = [] // 批量声明并赋值
2.2 let 块作用域的特征
// 1. 块儿级作用域(局部变量)
{
let zoo = "猫";
console.log(zoo);
}
console.log(zoo); // 报错:Uncaught ReferenceError: zoo is not defined
2.3 不能重复声明变量
// 2. 不允许重复声明
let abc = "ABC";
let abc = "ABC";
// 报错:Uncaught SyntaxError: Identifier 'ABC' has already been declared
3.const
- 声明必须赋初始值
- 不允许重复声明
- 变量标识符不允许修改
-
块级作用域(局部变量)
3.1 对象属性可以改吗?
const保证的并不是变量的值不能改动,而是变量指向的那个内存地址不能改动。对于基本类型的数据(数值、字符串、布尔值),其值就保存在变量指向的那个内存地址,因此等同于常量。
但对于引用类型的数据(主要是对象和数组)来说,变量指向数据的内存地址,保存的只是一个指针,const只能保证这个指针是固定不变的,至于它指向的数据结构是不是可变的,就完全不能控制了。
const obj = { a: 1, b: 2 };
console.log(obj.a); // 1
obj.a = 3;
console.log(obj.a); // 3
3.2 块级作用域
// 块儿级作用域(局部变量);
{
const cat = "猫";
console.log(cat); //猫
}
console.log(cat); //Uncaught ReferenceError: cat is not defined
注意:声明对象类型使用 const,非对象类型声明选择 let;
4. 区别
1.块级作用域:块作用域由 { }包括,let和const具有块级作用域,var 声明的变量属于函数作用域。
2.变量提升:var存在变量提升,let和const不存在变量提升 。
3.重复声明:而在同一个块级作用域,var声明变量时,可以重复声明变量,后声明的同名变量会覆盖之前声明的遍历。const和let不允许重复声明变量。
4.初始值设置: 在变量声明时,var 和 let 可以不用设置初始值。而const声明变量必须设置初始值。