var 和 let 的区别

337 阅读1分钟

let 不允许重复声明

let 不允许在同一作用域重复声明:

let a = 1
let a = 'hello'

// Uncaught SyntaxError: Identifier 'a' has already been declared

var 可以重复声明,并且后面的声明将前面的声明覆盖:

var a = 1
var a = 'hello'
console.log(a)

// hello

let 声明的变量是块级作用域变量

let 声明的变量是块级作用域变量:

{
    let a = 100
}
console.log(a)

// Uncaught ReferenceError: a is not defined at <anonymous>:5:13

var 声明的变量是全局变量:

{
    var a = 100
}
console.log(a)

// 100

let 没有变量提升

let 声明的变量不存在变量提升,并且必须在 let 声明变量后才可以使用该变量:

// 先使用,后声明
console.log(person1)
let person1 = 'kari'

// Uncaught SyntaxError: Identifier 'person1' has already been declaredat <anonymous>:1:1
// 先声明,后使用
let person1 = 'kari'
console.log(person1)

// kari

var 声明的变量会变量提升:

console.log(person1)
var person1 = 'kari'

// undefined

//等同于
var person = undefined
console.log(person1)
person1 = 'kari'

// undefined

let 会造成暂时性死区

由于 let 前面的特性,就很容易造成“暂时性死区”现象:

var s = 123;
if (true) {
  s = 'abc'
  let s
  console.log(s)
}

// Uncaught ReferenceError: s is not defined at <anonymous>:3:7

var 声明了全局变量 s,但是在块级作用域内 let 声明了变量 s 后,let 所声明的变量变绑定了这一作用域,不再受外部的影响。
并且必须在 let 声明变量后才可以使用该变量,但是上面代码由于没有先 let 声量变量,所以报错。

var 声明变量时不会造成“暂时性死区”现象:

var s = 123
if (true) {
  s = 'abc'
  var s
  console.log(s)
}

// abc