文章目录
  1. 1. 块作用域
    1. 1.1. with
    2. 1.2. try/catch
    3. 1.3. let

块作用域

with

with关键字不仅是一个难于理解的结构,同时也是块作用域的一个例子
(块作用域的一种形式),用with从对象中创建出的作用域仅在with声明中而非外部作用域中有
效。

try/catch

非常少有人会注意到JavaScript的ES3规范中规定try/catch的catch分句会创建一个块作用域,其
中声明的变量仅在catch内部有效。

尽管这个行为已经被标准化,并且被大部分的标准JavaScript环境(除了老版本的IE浏览
器)所支持,但是当同一个作用域中的两个或多个catch分句用同样的标识符名称声明错误变
量时,很多静态检查工具还是会发出警告。实际上这并不是重复定义,因为所有变量都被安全
地限制在块作用域内部,但是静态检查工具还是会很烦人地发出警告。
为了避免这个不必要的警告,很多开发者会将catch的参数命名为err1、err2等。也有开发者干
脆关闭了静态检查工具对重复变量名的检查。

let

let关键字可以将变量绑定到所在的任意作用域中(通常是{ ..}内部)。换句话说,let为其声明的变量隐式地了所在的块作用域。

1
2
3
4
5
6
7
var foo = true;
if (foo) {
let bar = foo * 2;
bar = something( bar );
console.log( bar );
}
console.log( bar ); // ReferenceError

用let将变量附加在一个已经存在的块作用域上的行为是隐式的。在开发和修改代码的过程中,如
果没有密切关注哪些块作用域中有绑定的变量,并且习惯性地移动这些块或者将其包含在其他的
块中,就会导致代码变得混乱。
为块作用域显式地创建块可以部分解决这个问题,使变量的附属关系变得更加清晰。通常来讲,显
式的代码优于隐式或一些精巧但不清晰的代码。显式的块作用域风格非常容易书写,并且和其他
语言中块作用域的工作原理一致:

1
2
3
4
5
6
7
8
9
var foo = true;
<b>if</b> (foo) {
{ // <-- 显式的快
let bar = foo * 2;
bar = something( bar );
console.log( bar );
}
}
console.log( bar ); // ReferenceError

只要声明是有效的,在声明中的任意位置都可以使用{ .. }括号来为let创建一个用于绑定的块。在
这个例子中,我们在if声明内部显式地创建了一个块,如果需要对其进行重构,整个块都可以被方
便地移动而不会对外部if声明的位置和语义产生任何影响。

使用let进行的声明不会在块作用域中进行提升。声明的代码被运行之前,声明并不”存在”。

1
2
3
4
{
console.log( bar ); // ReferenceError!
let bar = 2;
}
文章目录
  1. 1. 块作用域
    1. 1.1. with
    2. 1.2. try/catch
    3. 1.3. let