原文《5 Interesting Uses of JavaScript Destructuring》
翻译:范小饭
五种解构用法
看看我的JavaScript代码,我发现解构用法无处不在。
读取对象属性和访问数组项是频繁的操作。解构分配使这些操作变得更加简单和简洁。
在这篇文章中,我将在解构的基本用法之上,描述5种有趣的JavaScript解构用法。
1. 交换变量
交换变量的常规做法是添加一个临时变量。让我们看一段简单的脚本
let a = 1;
let b = 2;
let temp;
temp = a;
a = b;
b = temp;
a; // => 2
b; // => 1
temp是一个临时的变量存着a的值,b的值赋值给a,temp的值再赋值给b。
解构赋值使变量交换变得简单,而不需要临时变量
let a = 1;
let b = 2;
[a, b] = [b, a];
a; // => 2
b; // => 1
[a,b] = [b,a]是解构赋值。在右侧,创建一个数组[b,a],即[2,1]。该数组第一项2被分配给a,第二项1被分配给b
虽然您仍然创建临时数组,但使用解构赋值交换变量更简洁。
这不是限制。您可以同时交换2个以上的变量。我们试试看:
let zero = 2;
let one = 1;
let two = 0;
[zero, one, two] = [two, one, zero];
zero; // => 0
one; // => 1
two; // => 2
您可以根据需要交换尽可能多的变量!虽然,交换2个变量是最常见的情况
2.访问数组项
您有一个可能为空的项目。您想要访问数组的第一个,第二个或第n个项目,但如果该项目不存在,则获取默认值
通常你会使用数组的length属性:
const colors = [];
let firstColor = 'white';
if (colors.length > 0) {
firstColor = colors[0];
}
firstColor; // => 'white'
幸运的是,数组解构可以帮助以更短的方式实现。
const colors = [];
const [firstColor = 'white'] = colors;
firstColor; // => 'white'
const [firstColor = 'white'] = colors
把colors数组的第一项firstColor赋值为white,如果数组的第一项没有任何值,white就是默认值
但是有更多的灵活性。如果您只想访问第二个元素,那也是可能的:
const colors = [];
const [, secondColor = 'black'] = colors;
secondColor; // => 'black'
注意解构左侧的逗号:它表示忽略第一个元素。 secondColor使用colors数组中索引为1的元素进行赋值。
3.不可改变的操作
当我开始使用React和后来的Redux时,我被迫编写了一个尊重不变性的代码。虽然在开始时遇到一些困难,但后来我看到了它的好处:处理单向数据流更容易。
不变性禁止变异对象。幸运的是,解构可以帮助您轻松地以不可变的方式实现某些操作。
与... rest运算符组合的解构从数组的开头删除元素。
const numbers = [1, 2, 3];
const [, ...fooNumbers] = numbers;
fooNumbers; // => [2, 3]
numbers; // => [1, 2, 3]
[,... fooNumbers] = numbers
创建一个包含numbers的新的数组fooNumbers,只是除去了第一个元素。
numbers数组没有变,保持操作的不变性。
以同样的不变性,你可以删除对象的属性。让我们试着删除big对象里的foo属性。
const big = {
foo: 'value Foo',
bar: 'value Bar'
};
const { foo, ...small } = big;
small; // => { bar: 'value Bar' }
big; // => { foo: 'value Foo', bar: 'value Bar' }
与对象rest操作符组合的解构赋值创建一个小的新对象,所有属性都来自big,只有没有foo。
4.解构迭代
在前面的部分中,解构应用于数组。但是你可以解构任何实现可迭代协议的对象。
许多原始类型和对象是可迭代的:数组,字符串,类型化数组,集合和映射。
例如,您可以将字符串解构为字符:
const str = 'cheese';
const [firstChar = ''] = str;
firstChar; // => 'c'
您不仅限于原始类型。可以通过实现可迭代协议来定制解构逻辑。
movies包含电影对象列表。在解构movies时,将电影片名称为字符串会很棒。让我们实现一个自定义迭代器:
const movies = {
list: [
{ title: 'Heat' },
{ title: 'Interstellar' }
],
[Symbol.iterator]() {
let index = 0;
return {
next: () => {
if (index < this.list.length) {
const value = this.list[index++].title;
return { value, done: false };
}
return { done: true };
}
};
}
};
const [firstMovieTitle] = movies;
console.log(firstMovieTitle); // => 'Heat'
movies对象通过定义Symbol.iterator方法来实现可迭代协议。迭代器迭代电影的标题。
符合可迭代协议允许将电影对象解构为标题,特别是通过阅读第一部电影的标题:const [firstMovieTitle] = movies
The sky is the limit when using destructuring with iterators.
5.解构动态属性
根据我的经验,属性对对象的解构比数组解构更频繁。
对象的解构看起来很简单:
const movie = { title: 'Heat' };
const { title } = movie;
title; // => 'Heat'
const { title } = movie
创建了一个变量title,存储了movie.title的值。
当第一次阅读关于对象解构时,我有点惊讶你不必静态知道属性名称。您可以使用动态属性名称对对象进行结构化
要了解动态解构的工作原理,让我们编写一个问候函数:
function greet(obj, nameProp) {
const { [nameProp]: name = 'Unknown' } = obj;
return `Hello, ${name}!`;
}
greet({ name: 'Batman' }, 'name'); // => 'Hello, Batman!'
greet({ }, 'name'); // => 'Hello, Unknown!'
greet()有2个参数,对象和属性名。
在greet()里,const { [nameProp]: name = 'Unknown' } = obj
[nameProp]读取动态属性名称,name变量接收动态属性值。
如果属性不存在,您可以更好地指定默认值“未知”。
6.结论
解构对于访问对象的属性和数组项很有用。
除了基本用法之外,数组解构还可以方便地交换变量,访问数组项,执行一些不可变操作。
JavaScript提供了更大的可能性,因为您可以使用迭代器定义自定义解构逻辑。