什么是代码块?
可以这么理解,一个花括号“ { } ”就是一个代码块。用 let
声明的变量,只可以在花括号内部使用。let实际上为 JavaScript 新增了块级作用域。
在 let 命令声明变量 tmp 之前,都属于变量 tmp 的 “死区”
在没有 let
之前 typeof
是一个绝对安全的操作,不存在的全局变量直接打出 undefined
。如果一个变量根本没有被声明,使用 typeof
反而不会报错。
typeof tmp; // ReferenceError
let tmp;
typeof undeclared_variable; // undefined
ES6 规定暂时性死区和 let
、const
语句不出现变量提升
// 不报错
var x = x;
// 报错
let x = x;
// ReferenceError: x is not defined
ES6 规定暂时性死区和let
、const
语句不出现变量提升,主要是为了减少运行时错误,防止在变量声明前就使用这个变量,从而导致意料之外的行为。这样的错误在 ES5 是很常见的,现在有了这种规定,避免此类错误就很容易了。
总之,暂时性死区的本质就是,只要一进入当前作用域,所要使用的变量就已经存在了,但是不可获取,只有等到声明变量的那一行代码出现,才可以获取和使用该变量。
不允许重复声明
let
不允许在相同作用域内,重复声明同一个变量。
function a () {
let i = 12;
var i =13;
}; //报错
function b () {
let i = 0;
let i = 0;
}; //报错
function (res) {
let res;
}; //报错
function (res) {
{
let res;
}
}; //不报错
块级作用域
ES5 只有全局作用域和函数作用域,没有块级作用域,这带来很多不合理的场景。
- 内层变量可能会覆盖外层变量。
var tmp = new Date();
function f() {
console.log(tmp);
if (false) {
var tmp = 'hello world';
// tmp = 'hello word'; 此处放开又是另一种效果,一个是变量变量提升,一个是重新赋值,注意区别
}
}
f(); // undefined
上面代码的原意是,if
代码块的外部使用外层的 tmp
变量,内部使用内层的 tmp
变量。但是,函数f执行后,输出结果为 undefined
,原因在于变量提升,导致内层的 tmp
变量覆盖了外层的 tmp
变量。
- 用来计数的循环变量泄露为全局变量。
var s = 'hello';
for (var i = 0; i < s.length; i++) {
console.log(s[i]);
}
console.log(i); // 5
上面代码中,变量 i
只用来控制循环,但是循环结束后,它并没有消失,泄露成了全局变量。
let 实际上为 JavaScript 新增了块级作用域。
function f1() {
let n = 5;
if (true) {
let n = 10;
console.log(n); //10
}
console.log(n); // 5
};
表面上看声明了两个一样的变量 n
,但是 let
声明变量只在自己的块作用于内生效,所有打出 10 5;
ES6 允许块级作用域的任意嵌套。
{{{{let a = 'smile'}}}} //四层的块级作用域
网友评论