数组的解构赋值
基本用法
对称解构
只要等号两边的模式相同,左边的变量就会被赋予对应的值。
一次性给三个变量赋值:
1 2
| let [a, b, c] = [1, 2, 3]; let [x, , y] = [1, 2, 3];
|
给多维数组赋值:
1
| let [a, b, [c, d]] = [1, 2, [3, 4]];
|
rest:
1 2 3
| let [head, ...tail] = [1, 2, 3, 4]; tail
|
如果解构不成功则被赋值为 undefined
。
非对称解构
1 2
| let [x, y] = [1, 2, 3];
|
如果等号的右边是不可比遍历的解构则报错。
Set
1 2
| let [x, y, z] = new Set([1, 2, 3]);
|
只要数据类型具有Iterator接口就可以使用数组结构。
默认值
指定默认值:
1 2 3 4 5
| let [name = 'mason'] = []; name
let [x, y = 'b'] = ['a']; let [x, y = 'b'] = ['a', undefined];
|
es6内部判断一个位置是否有值: 严格等于 undefined
才会赋予默认值,也就是说除了 undefined
不能作为默认值其他都可以。
1 2 3 4 5
| let [x = 1] = [undefined];
let [x = 1] = [null];
|
如果默认值是一个表达式,那么这个表达式不会执行并返回值,因为表达式是惰性求值的。
1 2 3 4 5 6
| function f() { return 1; }
let [a = f()] = [2];
|
对象的解构赋值
1 2 3
| let {a, b} = {a:'a', b: 'b'};
|
对象的解构没有次序限制,变量名需要和属性名相同。
1 2 3
| let {a, b} = {b: 'b', a: 'a'};
|
如果解构失败,变量的值为undefined
。
使用对象解构赋值可以动态的给变量赋值:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| let Math = { log: function() {
}, sin: function() {
}, cos: function() {
}, tan: function() {
}, ... }; let {log, sin, cos} = Math;
|
如果变量名和属性名不一致,则要写成这样:
1 2 3 4
| let {a: aa, b: bb} = {b: 'b', a: 'a'};
|
也就是说对象的解构赋值是如下机制:先找到同名属性然后赋值给对应的变量。
1
| let {foo: foo, bar: bar} = {foo: 'a', bar: 'b'};
|
对象的解构也可以嵌套:
1 2 3 4 5 6 7 8 9 10
| let obj = { p: [ 'Hello', { y: 'World' } ] };
let { p: [x, { y }] } = obj; x y
|
默认值
对象的解构也可以指定默认值,具体同数组的解构一样。
默认值生效的条件是对象的属性值=== undefined
。
1 2 3 4 5 6 7
| let {x = 3} = {x: undefined};
let {x = 3} = {x: 1};
|
注意点
- 如何解构一个已经声明了的变量:
- 对于类似数组的对象也可以与数组结构
1 2
| let arr = [1, 2, 3]; let {0: 'a', 1: 'b', 2: 'c'} = arr;
|
字符串的解构赋值
对于非对象和数组的类型在被解构时会先被转为包装对象:
1 2 3 4
| let [a, b, c] = 'why';
let {length: len} = 'hello';
|
数值和布尔值的解构赋值
对于非对象和数组的类型在被解构时会先被转为包装对象:
1 2 3 4 5
| let {toString: s} = 123; s === Number.prototype.toString
let {toString: s} = true; s === Boolean.prototype.toString
|
undefined和null
undefined
和null
无法转为对象故而在结构时会报错。
函数参数的解构赋值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| function add([x, y]) { return x + y; } add([1, 2]);
function move(x = 0, y = 0) { return [x, y]; } move({x: 3, y: 8}); move({x: 3}); move({}); move();
function move({x, y} = { x: 0, y: 0 }) { return [x, y]; } move({x: 3, y: 8}); move({x: 3}); move({}); move();
|
圆括号问题
不能使用圆括号的情况
- 变量声明
- 参数函数
- 赋值语句模式
可以使用圆括号的情况
- 赋值语句的非模式部分
1 2 3
| [(a)] = [1]; ({p: (d)} = {}); [{parseInt.prop}] = [3];
|
变量解构的用途
- 交换变量
- 从函数返回多个值
函数只能return一个值,想要返回多个值就要把他们放到数组或者对象里面。
1 2 3 4 5 6 7 8
| function f() { return { foo: 1, bar: 2 }; } let {foo, bar} = f();
|
- 函数参数的定义
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
| let data = { name: 'wang', age: 22, isMarried: false };
let {name, age, isMarried} = data;
|
- 函数参数的默认值
1 2 3 4 5 6 7
| let f = function({ name = '', age = 0, isMarried = false, } = {}) { }
|
- 遍历Map
1 2 3 4 5 6 7 8 9
| const map = new Map(); map.set('first', 'hello'); map.set('second', 'world');
for (let [key, value] of map) { console.log(key + " is " + value); }
|
1 2 3 4 5 6 7 8 9
| for (let [key] of map) { }
for (let [,value] of map) { }
|
- 输入模块的指定方法
1
| const { SourceMapConsumer, SourceNode } = require("source-map");
|