- Promise承诺。承诺一件事,会立刻去执行,但是执行周期不确定,执行周期结束后执行结果:成功和失败不确定。
- 暂时性死区。 Let、Const命令声明 Tmp之前,Tmp是不能使用的,会报错,是属于 Tmp 的暂时性死区。 Var命令声明 Tmp之前是可以使用的,返回 Undefined未定义。
if (true) {// TDZ开始tmp = 'abc'; // 报错ReferenceErrorconsole.log(tmp); // ReferenceErrorlet tmp; // TDZ结束console.log(tmp); // undefinedtmp = 123;console.log(tmp); // 123}
有些“死区”比较隐蔽,不太容易发现。
function bar(x = y, y = 2) {return [x, y];}bar(); // 报错
上面代码中,调用 Bar函数之所以报错(某些实现可能不报错),是因为参数 X默认值等于另一个参数 Y,而此时 Y还没有声明,属于“死区”。如果 Y的默认值是 X,就不会报错,因为此时 X已经声明了。
function bar(x = 2, y = x) {return [x, y];}bar(); // [2, 2]
另外,下面的代码也会报错,与 Var的行为不同。
// 不报错var x = x;// 报错let x = x;// ReferenceError: x is not defined
上面代码报错,也是因为暂时性死区。使用 Let声明变量时,只要变量在还没有声明完成前使用,就会报错。上面这行就属于这个情况,在变量 X的声明语句还没有执行完成前,就去取 X的值,导致报错”x 未定义“。
- ES6在5的基础上增加了块作用域,原因在于没有块作用域的时候发生的两种情况:内部变量覆盖了外部变量,循环变量泄漏成全局变量。 内层变量可能会覆盖外层变量。
var tmp = new Date();function f() {console.log(tmp);if (false) {var tmp = 'hello world';}}f(); // undefined
代码块的外部使用外层的 Tmp变量,内部使用内层的 Tmp变量。但是,函数f执行后,输出结果为 Undefined,原因在于变量提升,导致内层的 Tmp变量覆盖了外层的 Tmp变量。
(2)用来计数的循环变量泄露为全局变量。
var s = 'hello';for (var i = 0; i < s.length; i++) {console.log(s[i]);}console.log(i); // 5
变量 I只用来控制循环,但是循环结束后并没有消失,泄露成了全局变量。
作用域 内层变量可以定义和外层变量同名的变量,反之报错。函数可以在块级作用域内声明,在块级作用域内声明的函数在块级作用域外不能引用。
- Const 声明一个只读的常量,一旦声明,常量的值不能改变。如果想赋值,需要在声明后立即初始化。实际上,不是变量的值不能改变,是变量所指向的内存地址的数据不能改变。 对于简单的数据(数值,字符串和布尔值等),Const是指向内存地址的数据,变量约等于常量。对于复合的数据(对象和数组等),保存的是指向实际数据的指针,Const只能保证这个指针是固定的,但指针指向但数据结构不可控。 将对象冻结,应该使用 Object.Freezee.
- 只要某种数据结构具有 Iterator 接口,都可以采用数组形式的解构赋值 之所以会报错,是因为 X用 Y做默认值时, Y还没有声明。
function* fibs() {let a = 0;let b = 1;while (true) {yield a;[a, b] = [b, a + b];}}let [first, second, third, fourth, fifth, sixth] = fibs();sixth // 5
let [x = 1, y = x] = []; // x=1; y=1let [x = 1, y = x] = [2]; // x=2; y=2let [x = 1, y = x] = [1, 2]; // x=1; y=2let [x = y, y = 1] = []; // ReferenceError: y is not defined
可以使用圆括号的情况只有一种:赋值语句的非模式部分,可以使用圆括号。
[(b)] = [3]; // 正确({ p: (d) } = {}); // 正确[(parseInt.prop)] = [3]; // 正确
都可以正确执行,因为首先它们都是赋值语句,而不是声明语句;其次它们的圆括号都不属于模式的一部分。第一行语句中,模式是取数组的第一个成员,跟圆括号无关;第二行语句中,模式是p,而不是d;第三行语句与第一行语句的性质一致。
