记录下ES6的一些容易忽略的规范:
-
let和const
1)只要块级作用域内存在let
命令,它所声明的变量就‘绑定’这个区域,不再受外部的影响。
ES6明确规定,如果区块中存在let
和const
命令,这个区域对这些命令声明的变量,从一开始就形成了封闭作用域。凡是在声明之前就使用这些变量,就会报错。
总之,在代码块内,使用let
命令声明变量之前,该变量都是不可用的。在语法上称为“暂时性死区”(temporal dead zone, 简称TDZ)。//例1: for(let index = 0; index < 3; index ++) { console.log(index); //ReferenceError let index = 9527; console.log(index); } //例2: let x = x;//ReferenceError //例3: var x = x;//undefined
注意:ES6的块级作用域必须有大括号,如果没有大括号,js引擎就认为不存在块级作用域。
// 第一种写法,报错 if(true) let x = 1; // 第二种写法,不报错 if(true) { let x = 1; }
2)
const
实际上保证的,并不是变量的值不得改动,而是变量指向的那个内存地址所保存的数据不得改动。对于简单类型的数据,值就保存在变量指向的内存地址,保存的知识一个指向实际数据的指针,const
只能保证这个指针是固定的(即总是指向另一个固定的地址),至于它指向的数据结构是不是可变的,就完全不能控制了。因此,将一个对象声明为常量必须非常小心。const foo = {}; foo.prop = 123; foo.prop // 123 foo = {}; // TypeError: "foo" is read-only
-
数组的解构与赋值
// ES5 let a = 1; let b = 2; let c = 3; //ES6 let [a, b, c] = [1, 2, 3]; // 嵌套赋值 let [a, [b, [c]]] = [1, [2, [3]]]; //a == 1, b == 2, c == 3 // 定义默认值 let [x = 1, y] = []
注意:ES6内部使用严格相等运算符(
===
),判断一个位置是否有值。所以,只有当一个数组成员严格等于undefined
,默认值才会生效。
如果默认值是一个表达式,那么这个表达式是惰性求值的,即只有在用到的时候,才会求值。function f() { console.log('aaa'); } let [x = f()] = [1];
上述代码中
f
函数不会执行。上面代码等价于下面的代码:let x; if([1][0] === undefined) { x = f(); } else { x = [1][0]; }
如果变量名与属性名不一致必须写成下面这样:
let { foo: baz } = { foo: 'aaa', bar: 'bbb'}; // baz=='aaa' let obj = {first: 'hello', last: 'world'}; let {first: f, last: 1} = obj; //f == 'hello', last = 'world'
也就是说,对象的解构赋值的内部机制,是先找到同名属性,然后再赋值给对应的变量。真正被赋值的是厚泽,而不是前者。
let {foo: baz} = {foo: 'aaa', bar: 'bbb'}; //baz == 'aaa' foo // error: foo is not defined
注意点:
1)如果要将一个已声明的变量用于解构赋值,必须非常小心。let x; {x} = {x: 1};//SyntaxError: syntax error
因为js引擎会将
{x}
理解成一个代码块,从而发生语法错误。只有不将大括号写在首行,避免js将其解释为代码块,才能解决这个问题。let x; ({x} = {x: 1});
2)由于数组本质是非常特殊的对象,因此可以对数组进行对象属性的解构。
let arr = [1, 2, 3]; let {0: first, [arr.length - 1]: last} = arr; //first == 1, last == 3
-
字符串的解构赋值
字符串也可以解构赋值。这是因为此时,字符串被转换成了一个类似数组的对象。const [a, b, c, d, e] = 'hello'; //a == 'h', b == 'e'....
类似数组的对象都有一个
length
属性,因此还可以对这个属性解构赋值。let {length: len} = 'hello'; //len == 5;