ECMAScript 6 块级作用域与 let 声明详解

作者:异步漫步时间:2026-10-29 11:01:04浏览:447

本文介绍 ECMAScript 6 引入的 let 命令及其块级作用域特性。通过对比 var,详细解析 let 在 if 和 for 语句中的作用域限制、消除变量提升现象以及暂时性死区(TDZ)机制,并说明其在替代匿名函数自执行中的作用。

块级作用域与 let 概述

许多编程语言都具备块级作用域,但 JavaScript 传统上并不支持,而是通过 var 关键字声明变量,并以 function 来划分作用域范围。在 JavaScript 中,大括号“{}”无法限制 var 声明变量的作用域。此外,使用 var 声明的变量会表现出变量提升(declaration hoisting)的行为。

ES6 引入了 let 命令,允许在 {}、if 语句和 for 循环等代码块中进行声明。其基本用法与 var 类似,但关键区别在于 let 声明的变量作用域被严格限制在块级范围内,且 let 声明的变量不会发生变量提升。

if 语句中的块级作用域

示例1: 块级作用域 if


function getVal(boo) {
  if (boo) {
    var val = 'red'
    // ...
    return val
  } else {
    // 这里可以访问 val
    return null
  }
  // 这里也可以访问 val
}

当变量 val 在 if 代码块内部使用 var 声明时,该变量在 else 代码块以及 if 块外部依然可以被访问到。

若将 var 替换为 let,变量 val 的作用域将被限制在 if 代码块内部,导致在 else 块及 if 外部无法访问该变量。


function getVal(boo) {
  if (boo) {
    let val = 'red'
    // ...
    return val
  } else {
    // 这里访问不到 val
    return null
  }
  // 这里也访问不到 val
} 

for 循环中的块级作用域

示例2: 块级作用域 for


function func(arr) {
  for (var i = 0; i < arr.length; i++) {
    // i ...
  }
  // 这里也可以访问到i
}

当变量 i 在 for 循环内部使用 var 声明时,即使循环结束,变量 i 在 for 循环外部仍然可以被访问。

若将 var 替换为 let,变量 i 的作用域将仅限于 for 循环内部,导致在 for 循环外部无法访问变量 i。


function func(arr) {
  for (let i = 0; i < arr.length; i++) {
    // i ...
  }
  // 这里访问不到i
}

变量提升与暂时性死区

示例3: 变量提升(先使用后声明)


function func() {
  // val先使用后声明,不报错
  alert(val) // undefined
  var val;
}

在使用 var 声明的情况下,如果变量 val 在声明之前被使用(先使用后声明),代码不会报错,但输出结果为 undefined。

若将 var 替换为 let,在声明之前使用变量 val 会直接导致语法错误。


function func() {
  // val先使用后声明,报语法错
  alert(val)
  let val;
} 

示例4: 变量提升(先判断后声明)


function func() {
  if (typeof val == 'undefined') {
    // ...
  }
  var val = ''
}

在使用 typeof 进行判断时,即使代码位于 var 语句之前,也不会报错。

然而,若将 var 替换为 let,在 if 语句处执行时会抛出语法错误。


function func() {
  if (typeof val == 'undefined') {
    // ...
  }
  let val = '';
}

ES6 规定,如果代码块中存在 let 声明,该区块从开始执行起就形成了封闭的作用域。凡是在声明之前使用变量,就会报错。即在代码块内,在 let 声明之前使用变量都是不可用的。语法上有一个术语称为“暂时性死区”(temporal dead zone),简称 TDZ。需要注意的是,TDZ 并未出现在 ES 规范中,它仅用于形象地描述这一现象。

let 的使用注意事项

let 的注意事项

1. 不能重复声明


// var和let重复声明
var name = 'Jack';
let name = 'John';
 
// 两个let重复声明
let age = 24;
let age = 30;

在执行时,如果尝试对同一变量进行重复声明,会抛出语法错误。

2. 有了 let 后,匿名函数自执行就可以去掉了


// 匿名函数写法
(function () {
 var jQuery = function() {};
 // ...
 window.$ = jQuery
})();
 
// 块级作用域写法
{
 let jQuery = function() {};
 // ...
 window.$ = jQuery;
}

以上所述就是本文的全部内容了,希望大家能够喜欢。

作者最新文章