全局块级绑定
let 与 const 不同于 var 的另一个方面是在全局作用域上的表现。当在全局作用域上使用 var 时,它会创建一个新的全局变量,并成为全局对象(在浏览器中是 window)的一个属性。这意味着使用 var 可能会无意覆盖一个已有的全局属性,就像这样:
// 在浏览器中
var RegExp = "Hello!";
console.log(window.RegExp); // "Hello!"
var ncz = "Hi!";
console.log(window.ncz); // "Hi!"
尽管全局的 RegExp 是定义在 window 上的,它仍然不能防止被 var 重写。这个例子声明了一个新的全局变量 RegExp 而覆盖了原有对象。类似的,ncz 定义为全局变量后就立即成为了 window 的一个属性。这就是 JS 通常的工作方式。
然而若你在全局作用域上使用 let 或 const,虽然在全局作用域上会创建新的绑定,但不会有任何属性被添加到全局对象上。这也就意味着你不能使用 let 或 const 来覆盖一个全局变量,你只能将其屏蔽。这里有个范例:
// 在浏览器中
let RegExp = "Hello!";
console.log(RegExp); // "Hello!"
console.log(window.RegExp === RegExp); // false
const ncz = "Hi!";
console.log(ncz); // "Hi!"
console.log("ncz" in window); // false
此代码的 let 声明创建了 RegExp 的一个绑定,并屏蔽了全局的 RegExp。这表示 window.RegExp 与 RegExp 是不同的,因此全局作用域没有被污染。同样,const 声明创建了 ncz 的一个绑定,但并未在全局对象上创建属性。当你不想在全局对象上创建属性时,这种特性会让 let 与 const 在全局作用域中更安全。
若想让代码能从全局对象中被访问,你仍然需要使用 |