ES6解构赋值

配置文件.babelrc

Babel的配置文件是.babelrc,存放在项目的根目录下。使用Babel的第一步,就是配置这个文件。

ES草案阶段
  • Stage 0 - Strawman(展示阶段)
  • Stage 1 - Proposal(征求意见阶段)
  • Stage 2 - Draft(草案阶段)
  • Stage 3 - Candidate(候选人阶段)
  • Stage 4 - Finished(定案阶段)
let和const 命令

let不像var那样会发生“变量提升”现象(就是var 定义了 然后输出undefined,let 直接报错 )。所以,变量一定要在声明后使用,否则报错。

ES6的块级作用域

let实际上为JavaScript新增了块级作用域。

块级作用域的出现,实际上使得获得广泛应用的立即执行匿名函数(IIFE)不再必要了。

1
2
3
4
5
6
7
8
9
10
11
// IIFE写法
(function () {
var tmp = ...;
...
}());
// 块级作用域写法
{
let tmp = ...;
...
}

下面的代码如果使用var 输出的是 10

1
2
3
4
5
6
7
var a = [];
for (var i = 0; i < 10; i++) {
a[i] = function () {
console.log(i);
};
}
a[6](); // 10

如果使用let,声明的变量仅在块级作用域内有效,最后输出的是6。

1
2
3
4
5
6
7
var a = [];
for (let i = 0; i < 10; i++) {
a[i] = function () {
console.log(i);
};
}
a[6](); // 6
不存在变量提

let不像var那样会发生“变量提升”现象。所以,变量一定要在声明后使用,否则报错。

变量不允许重复声明

let不允许在相同作用域内,重复声明同一个变量。

解构赋值
直接赋值
1
var [a, b, c] = [1, 2, 3];
Set 赋值
1
let [x, y, z] = new Set(["a", "b", "c"]);
默认值

如果一个数组成员不严格等于undefined,默认值是不会生效的。

1
2
let [x, y = 'b'] = ['a', undefined];
console.log(x,y)

如果一个数组成员是null,默认值就不会生效,因为null不严格等于undefined。

1
2
3
4
5
var [x = 1] = [undefined];
x // 1
var [x = 1] = [null];
x // null

默认值可以引用解构赋值的其他变量,但该变量必须已经声明。

1
2
3
4
let [x = 1, y = x] = []; // x=1; y=1
let [x = 1, y = x] = [2]; // x=2; y=2
let [x = 1, y = x] = [1, 2]; // x=1; y=2
let [x = y, y = 1] = []; // ReferenceError
对象的解构赋值
1
var { foo: foo, bar: bar } = { foo: "aaa", bar: "bbb" };

对象的解构也可以指定默认值。

1
2
3
4
5
6
7
8
9
var {x = 3} = {};
x // 3
var {x, y = 5} = {x: 1};
x // 1
y // 5
var { message: msg = "Something went wrong" } = {};
msg // "Something went wrong"

现有对象方法赋值到某个变量

1
let { log, sin, cos } = Math;

解析出来的结果类似 代码

1
2
3
4
"use strict";
var log = Math.log;
var sin = Math.sin;
var cos = Math.cos;

字符串的解构赋值

字符串也可以解构赋值。这是因为此时,字符串被转换成了一个类似数组的对象。

1
2
3
4
5
6
const [a, b, c, d, e] = 'hello';
a // "h"
b // "e"
c // "l"
d // "l"
e // "o"

类似数组的对象都有一个length属性,因此还可以对这个属性解构赋值。

1
2
let {length : len} = 'hello';
len // 5
数值和布尔值的解构赋值

解构赋值时,如果等号右边是数值和布尔值,则会先转为对象。

1
2
3
4
5
let {toString: s} = 123;
s === Number.prototype.toString // true
let {toString: s} = true;
s === Boolean.prototype.toString // true

函数参数的解构赋值
1
2
3
4
function add([x, y]){
return x + y;
}
add([1, 2]); // 3
解构赋值用途
交换变量的值
1
[x, y] = [y, x];
从函数返回多个值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 返回一个数组
function example() {
return [1, 2, 3];
}
var [a, b, c] = example();
// 返回一个对象
function example() {
return {
foo: 1,
bar: 2
};
}
var { foo, bar } = example();
函数参数的定义
1
2
3
4
5
6
7
// 参数是一组有次序的值
function f([x, y, z]) { ... }
f([1, 2, 3]);
// 参数是一组无次序的值
function f({x, y, z}) { ... }
f({z: 3, y: 2, x: 1});
提取JSON数据
1
2
3
4
5
6
7
8
9
10
var jsonData = {
id: 42,
status: "OK",
data: [867, 5309]
};
let { id, status, data: number } = jsonData;
console.log(id, status, number);
// 42, "OK", [867, 5309]
遍历Map结构
1
2
3
4
5
6
7
8
9
var map = new Map();
map.set('first', 'hello');
map.set('second', 'world');
for (let [key, value] of map) {
console.log(key + " is " + value);
}
// first is hello
// second is world

如果只想获取键名,或者只想获取键值,可以写成下面这样。

1
2
3
4
5
6
7
8
9
// 获取键名
for (let [key] of map) {
// ...
}
// 获取键值
for (let [,value] of map) {
// ...
}
字符串的扩展

传统上,JavaScript只有indexOf方法,可以用来确定一个字符串是否包含在另一个字符串中。ES6又提供了三种新方法。

includes()

返回布尔值,表示是否找到了参数字符串。

1
2
3
4
5
var s = 'Hello world!';
if(s.includes('ld')) {
console.log(1)
}
startsWith()

返回布尔值,表示参数字符串是否在源字符串的头部。

1
s.endsWith('!') // true
endsWith()

返回布尔值,表示参数字符串是否在源字符串的尾部。

1
s.endsWith('!') // true

这三个方法都支持第二个参数,表示开始搜索的位置。

1
2
3
4
5
const s = 'Hello world!';
s.startsWith('world', 6) // true
s.endsWith('Hello', 5); // true
s.endsWith('Hell', 4); // true
s.includes('Hello', 6) // false
字符串模板
1
2
3
// 字符串中嵌入变量
let name = "Bob", time = "today";
console.log(`Hello ${name}, how are you ${time}?`)

模板字符串都是用 `, 也可以用来调用函数

1
2
3
4
function add() {
console.log(1222);
}
let str = `Nihai ${add()}`;
0%