1、ES6 解构赋值、数组解构
ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring)。
let [a,b,c] = [1,2,3];
console.log(b);
let [foo, [[bar], baz]] = [1, [[2], 3]];
let [ , , third] = [1, 2, 3];
console.log(third);
let [head, ...tail] = [1,2,3,4];
head; // 1
console.log(tail); // [2,3,4]
let [x,y,...z] = ['geek'];
x; // 'geek'
y; // undefined // 如果解构不成功,变量的值就等于undefined。
console.log(z); // []
对Set结构进行解构:
let [m,n] = new Set(['1', '2']);
console.log(m);
事实上,只要某种数据结构具有 Iterator 接口,都可以采用数组形式的解构赋值。
解构赋值允许指定默认值:
let [foo = true] = [];
foo; // true
let [s, t = 2] = [1];
t; // 2
let [w, v='xia'] = ['geek', undefined];
v; // 'xia'
let [j = 1] = [undefined];
j; // 1
let [h = 1] = [null];
h; // null
// 因为 null !== undefined
let [x = 1, y = x] = [];
// x = y = 1;
let [x = 1, y = x] = [100];
// x = y = 100;
let [x = 1, y = x] = [200, 300];
// x = 200, y = 300
let [x = y, y = 1] = [1]; // 报错,y is undefined
2、解构不仅可以用于数组,还可以用于对象
对象的解构与数组的解构 有一个重要的不同。数组的元素是按次序排列的,变量的取值由它的位置决定;而对象的属性没有次序,变量必须与属性同名,才能取到正确的值。
let obj = {foo: 'aaa', bar: 'bbb'};
let { foo, geek } = obj;
console.log(foo); // 'aaa'
console.log(geek); // undefined
let { bar: b } = obj;
console.log(b); // 'bbb'
let { foo: f } = { foo: 'geek' };
// foo is undefined // foo是匹配模式
// f = 'geek'; // f 才是变量
对象解构嵌套:
let obj2 = {
p: ['hello', {y: 'world'}]
};
let {p: [x:x, {y:z}]} = obj2;
// x = 'hello'
// z = 'world'
// p 是匹配模式,它不是变量
// y 是匹配模式,它不是变量
对象解构 与 匹配模式:
const node = {
loc: {
start: {
line: 1,
column: 4
}
}
}
let { loc, loc: {start}, loc: {start: {line, column}}} = node;
// loc变量
// start变量
// line变量
// : 前面的是匹配模式
let obj3 = {};
let arr3 = [];
({foo: obj3.prop, bar: arr3[0]} = { foo: 123, bar: true});
// foo 是匹配模式, obj3.prop 是变量
// bar 是匹配模式, arr3[0] 是变量
对象解构 指定默认值:
var { x = 3 } = { x: undefined };
// x = 3
let { y = 3} = { y : null };
// y = null
实例,从Math对象中解构出三个函数:
let { log, sin, cos } = Math;
由于数组本质是特殊的对象,因此可以对数组进行对象属性的解构。
let arr = [1, 2, 3];
let {0: first, 1: second, [arr.length-1]: last} = arr;
// first = 1
// second = 2
// last = 3
// 把数组看成特殊的对象
let arrObj = {
0: 1,
1: 2,
3: 2
}
3、字符串的解构赋值
const [a,b,c,d,e] = 'hello';
// a = 'h'
// e = 'o'
let {length: len} = 'hello';
// length是匹配模式,字符串有这个属性
// len = 5
4、数值和布尔值的解构赋值
let { toString: s } = 123;
let { toString: t } = true;
5、函数参数的解构赋值
function add([x,y]) {
return x + y;
}
add([1,2]); // 3
[[1,2], [3,4]].map(([a,b]) => a + b);
// [3, 7]
函数参数解构使用默认值:
function move({x=0, y=0} = {}) {
return [x,y];
}
move({x:3, y:8}); // [3,8]
move({x:3}); // [3,0]
move(); // [0,0]
[1, undefined, null, true].map((x = 'yes') => x);
// [1, 'yes', null, true]
6、解构赋值 与 圆括号问题
let [(a)] = [1]; // 报错,模式不能使用圆括号
[(b)] = [3]; // 正确,赋值语句的非模式部分,可以使用圆括号
7、解构赋值的应用
应用1:交换两个变量的值
let x = 1;
let y = 2;
[x, y] = [y, x];
console.log(x,y); // 2, 1
应用2:从函数中返回多个值
函数只能返回一个值,如果要返回多个值,只能将它们放在数组或对象里返回。有了解构赋值,取出这些值就非常方便。
function returnArray() {
// 返回一个数组
return [1, 2, 3];
}
let [a, b, c] = returnArray();
function returnJson() {
// 返回一个对象
return {
m: 1,
n: 2
}
}
let { m, n: aN } = returnJson();
应用3:函数参数的定义
解构赋值可以方便地将一组参数与变量名对应起来。
// 有序参数
function f1([x,y,z]) { };
f1([1, 2, 3]);
// 无序参数
function f2({x,y,z}) { };
f({ z: 3, x: 1, y: 2});
应用4:提取JSON中的数据
let data = {
id: 42,
status: 'ok',
names: ['geek', 'xia']
}
let { id, status, names:myNames } = data;
应用5:函数参数的默认值
jQuery.ajax = function(url, {
async = true,
beforeSend = function() {},
cache = true,
complete = function() {},
crossDomain = false,
global = true,
method = 'GET'
} = {}) {
// do something
}
// 调用并覆盖部分默认参数
jQuery.ajax(url, {method: 'POST', async: false});
应用6:遍历Map结构
任何部署了 Iterator 接口的对象,都可以用for...of循环遍历。Map 结构原生支持 Iterator 接口,配合变量的解构赋值,获取键名和键值就非常方便。
const map = new Map();
map.set('a', 1);
map.set('b', 2);
// 从Map结构中取出所有键值
for(let [key, value] of map) {
console.log(key + ' - ' + value);
}
// 只获取键名
for(let [key] of map) {
console.log(key);
}
// 只获取值
for(let [value] of map) {
console.log(value);
}
应用7:使用模块中的指定方法
const { method1, method2 } = require('source-map');
完!!!
网友评论