let命令

let命令


let命令,用来声明变量。它的用法类似于var,但是所声明的变量,只在let命令所在的代码块内有效。let不允许在相同作用域内,重复声明同一个变量。let适用于for循环.

{
  let a = 10
  var b = 1
}

a // ReferenceError: a is not defined.
b // 1

var声明的变量都是全局变量,let则为局部变量

var a = []
for (var i = 0; i < 10; i++) {
  a[i] = function () {
    console.log(i)
  }
}
a[6]() // 10

以上代码for循环var换为let,则结果为6

变量提升问题

let不存在变量提升问题,而var存在

// var 的情况
console.log(foo) // 输出undefined
var foo = 2

// let 的情况
console.log(bar) // 报错ReferenceError
let bar = 2

暂时性死区

只要块级作用域内存在let命令,它所声明的变量就“绑定”(binding)这个区域,不再受外部的影响。

var tmp = 123

if (true) {
  tmp = 'abc' // ReferenceError
  let tmp
}

上面代码中,存在全局变量tmp,但是块级作用域内let又声明了一个局部变量tmp,导致后者绑定这个块级作用域,所以在let声明变量前,对tmp赋值会报错。
所以,在代码块内,使用let(const)命令声明变量之前,该变量都是不可用的。这在语法上,称为“暂时性死区”(简称TDZ)。

if (true) {
  // TDZ开始
  tmp = 'abc' // ReferenceError
  console.log(tmp) // ReferenceError

  let tmp
  // TDZ结束
  console.log(tmp) // undefined

  tmp = 123
  console.log(tmp) // 123
}

“暂时性死区”也意味着typeof不再是一个百分之百安全的操作。

typeof x // ReferenceError
let x

上面代码中,变量x使用let命令声明,所以在声明之前,都属于x的“死区”,只要用到该变量就会报错。作为比较,如果一个变量根本没有被声明,使用typeof反而不会报错。

typeof undeclared_variable // "undefined"

一些隐蔽的死区

function bar(x = y, y = 2) {
  return [x, y]
}

bar() // 报错

上面代码中,调用bar函数之所以报错(某些实现可能不报错),是因为参数x默认值等于另一个参数y,而此时y还没有声明,属于”死区“。如果y的默认值是x,就不会报错,因为此时x已经声明了。

function bar(x = 2, y = x) {
  return [x, y]
}
bar() // [2, 2]

下面代码报错,也是因为暂时性死区。使用let声明变量时,只要变量在还没有声明完成前使用,就会报错。

// 不报错
var x = x

// 报错
let x = x
// ReferenceError: x is not defined

你可能感兴趣的:(ES6)