1. var
var 声明的变量属于函数作用域
如果使用关键字 var 声明一个变量,那么这个变量就属于当前的函数作用域,如果声明是发生在任何函数外的顶层声明,那么这个变量就属于全局作用域。
var a = 123 //此处声明的变量a为全局变量
function foo(){
var a = 321 // 此处声明的变量a为函数foo的局部变量
console.log(a) // 321
}
foo()
console.log(a) // 123
var 声明的变量存在提升(hoisting)
提升是指无论 var 出现在一个作用域的哪个位置,这个声明都属于当前的整个作用域,在其中到处都可以访问到。注意只有变量声明才会提升,对变量赋值并不会提升。
console.log(a) // undefined
var a = 123
该代码段跟下列代码段是一样的逻辑:
var a
console.log(a) // undefined
a = 123
而如果对未声明过的变量进行操作,就会报错:
console.log(b) // 假设b未声明过,Uncaught ReferenceError: b is not defined
var 变量可以重复声明
如果在声明变量时,省略 var 的话,该变量就会变成全局变量,如全局作用域中存在该变量,就会更新其值。
var a = 123 // 此处声明的变量a为全局变量
function foo(){
a = 321 // 此处的变量a也是全局变量
console.log(a)// 321
}
foo()
console.log(a) // 123
2. let
let命令,用来声明变量。它的用法类似于var,但是所声明的变量,只在let命令所在的代码块内有效。
-
let 声明的变量具有块作用域(局部变量)的特征。
// 1. 块儿级作用域(局部变量) { let cat = "猫" console.log(cat) } console.log(cat) // 报错:Uncaught ReferenceError: cat is not defined -
let 在同一个块级作用域(局部变量),不能重复声明变量。
// 2. 不允许重复声明 let dog = "狗" let dog = "狗" // 报错:Uncaught SyntaxError: Identifier 'dog' has already been declared -
let 声明的变量不存在变量提升,存在暂时性死区(TDZ)。
var people1 = "大哥" // 存在变量提升 let people2 = "二哥" // 不存在变量提升 -
let 不影响作用域链v
// 4. 不影响作用域链; let p = "大哥" function fn(){ console.log(p) // 这里是可以使用的 } fn()
3. const
const 声明方式,除了具有 let 的上述特点外,其还具备一个特点,即 const 定义的变量,一旦定义后,就不能修改,即 const 声明的为常量。
- 声明必须赋初始值;
- 标识符一般为大写(习惯);
- 不允许重复声明;
- 变量标识符不允许修改;
- 块儿级作用域(局部变量);