本文介绍 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;
}
以上所述就是本文的全部内容了,希望大家能够喜欢。