转载请注明原文地址:
感谢阮一峰老师的无私奉献,开源推动世界!教程地址:
一:let与const命令
1:let命令
ES6新增了let
命令,用来声明变量。它的用法类似于var
,但是所声明的变量,只在let
命令所在的代码块内有效。——let命令弥补了ES语法一切皆公开的弊端,起到了局部变量的功能,增加了块级作用域。
for
循环的计数器,就很合适使用let命令来声明,它只在for循环体内有效。
let
不像var
那样会发生“变量提升”(声明语句可以写在后面,在运行时会重排列,把声明语句先解释)。所以,变量一定要在声明后使用,否则报错。
暂时性死区:在代码块内,若有let、const声明的变量,则在该代码块中,遇到该变量的声明语句前使用该变量都会报错。并且,块内变量覆盖块外全局同名变量。那么,从代码块开始~变量声明语句前,这片区域就叫做暂时性死区。暂时性死区的本质就是,只要一进入当前作用域,所要使用的变量就已经存在了,但是不可获取,只有等到声明变量的那一行代码出现,才可以获取和使用该变量。
if (true) { // TDZ开始 tmp = 'abc'; // ReferenceError console.log(tmp); // ReferenceError let tmp; // TDZ结束 console.log(tmp); // undefined tmp = 123; console.log(tmp); // 123}
不允许重复声明
在let命令存在的代码中,不允许有同名的变量声明语句出现,会报错;也不允许在函数内部声明与参数同名的变量;
// 报错function () { let a = 10; var a = 1;}// 报错function () { let a = 10; let a = 1;}function func(arg) { let arg; // 报错}
2:const命令
const
声明一个只读的常量。一旦声明,常量的值就不能改变。
对于const
来说,只声明不赋值,就会报错。
const
的作用域与let
命令相同:只在声明所在的块级作用域内有效。
const
命令声明的常量也是不提升,同样存在暂时性死区,只能在声明的位置后面使用。
const
声明的常量,也与let
一样不可重复声明。
ES5只有两种声明变量的方法:var
命令和function
命令。ES6除了添加let
和const
命令,还有另外两种声明变量的方法:import
命令和class
命令。所以,ES6一共有6种声明变量的方法。
二:变量的解构赋值
ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring)。
本质上,这种写法属于“模式匹配”,只要等号两边的模式相同,左边的变量就会被赋予对应的值。
1:数组解构
let [a, b, c] = [1, 2, 3];//数组解构赋值let [ , , third] = ["foo", "bar", "baz"];
另一种情况是不完全解构,即等号左边的模式,只匹配一部分的等号右边的数组。这种情况下,解构依然可以成功。
let [x, y] = [1, 2, 3];
如果等号的右边不是可遍历的结构,那么将会报错。
// 报错let [foo] = 1;let [foo] = false;let [foo] = NaN;let [foo] = undefined;let [foo] = null;let [foo] = {};
只要右边的具有可迭代接口,就可以用来解构赋值。
可以指定默认值,在右侧没有对应位置的值时作为左侧变量的值:
let [x, y = 'b'] = ['a']; // x='a', y='b'
2:对象解构赋值:左侧:用{}括起对象,花括号内用逗号分隔符声明一系列属性。
右侧:用{}括起来表示对象,用键值对的形式为对象的属性们进行赋值,注意:右侧赋值的属性必须在左侧声明过!
let { bar, foo } = { foo: "aaa", bar: "bbb" };
对于复杂的数据,可以在需要赋值的属性前加一个模式标志,在右侧赋值的时候也用模式来定位:
let obj = { p: [ 'Hello', { y: 'World' } ]};let { p: [x, { y }] } = obj;
3:字符串解构赋值
const [a, b, c, d, e] = 'hello';
4:函数参数解构赋值:可以用数组作为函数参数,在调用函数的时候传数组就可以按顺序赋值。
function add([x, y]){ return x + y;}add([1, 2]);
5:解构赋值的应用场景
1)交换两个变量值:
[x, y] = [y, x];
2)从函数返回多个值,按顺序解构赋值给左侧变量:
function example() { return { foo: 1, bar: 2 };}let { foo, bar } = example();
3)调用函数时,解构赋值给函数参数:
// 参数是一组有次序的值function f([x, y, z]) { ... }f([1, 2, 3]);// 参数是一组无次序的值function f({x, y, z}) { ... }f({z: 3, y: 2, x: 1});
4)提取json数据,解构赋值给左侧变量:
let jsonData = { id: 42, status: "OK", data: [867, 5309]};let { id, status, data} = jsonData;
5)遍历map,解构获取每对键和值:
//获取键值对for (let [key, value] of map) { //TODO}// 获取键for (let [key] of map) { // ...}// 获取值for (let [,value] of map) { // ...}
6)加载模块时,指定输入哪些方法:
const { SourceMapConsumer, SourceNode } = require("source-map");