10.10 解构示例
让我们以几个更小的例子开始。
for-of
循环支持解构:
let map = new Map().set(false, 'no').set(true, 'yes');
for (let [key, value] of map) {
console.log(key + ' is ' + value);
}
可以使用解构来交换变量值,引擎会优化这个过程,因此不会创建额外的数组。
[a, b] = [b, a];
可以使用解构来分离数组:
let [first, ...rest] = ['a', 'b', 'c'];
// first = 'a'; rest = ['b', 'c']
10.10.1 解构返回值
一些内置的 JavaScript 操作返回数组,解构可以辅助处理返回的数组:
let [all, year, month, day] =
/^(\d\d\d\d)-(\d\d)-(\d\d)$/
.exec('2999-12-31');
10.10.2 多个返回值
为了看一下很有用的多值返回,让我们事先一个函数 findElement(a, p)
,该函数查找数组 a
中第一个使函数 p
返回 true
的元素。问题是:这个函数要返回什么?有时可能对满足条件的那个元素感兴趣,有时是元素的索引,有时是两者都感兴趣。下面的实现两者都返回。
function findElement(array, predicate) {
for (let [index, element] of array.entries()) { // (A)
if (predicate(element)) {
return { element, index }; // (B)
}
}
return { element: undefined, index: -1 };
}
在 A 行,数组方法 entries()
返回一个迭代器,迭代器的每个元素是一个 [index, element]
对。每次迭代解构一个元素。在 B 行,使用属性值缩写返回对象 { element: element, index: index }
。
使用 findElement()
。在下面的例子中,一些 ECMAScript 6 特性允许我们书写更加简明的代码:回调函数是一个箭头函数,返回值通过对象模式的属性值简写来解构。
let arr = [7, 8, 6];
let {element, index} = findElement(arr, x => x % 2 === 0);
// element = 8, index = 1
由于 index
和 element
也指向属性键,它们书写的顺序是无关紧要的:
let {index, element} = findElement(···);
我们成功处理了同事使用索引和元素的情况。如果只对其中某一个感兴趣怎么办?事实证明,感谢 ECMAScript 6 ,我们的实现也同样能处理这种情形,并且相对于返回单一值的函数,语法开销是最小的。
let a = [7, 8, 6];
let {element} = findElement(a, x => x % 2 === 0);
// element = 8
let {index} = findElement(a, x => x % 2 === 0);
// index = 1
每一次,仅提取需要的属性值。