专栏名称: SegmentFault思否
SegmentFault (www.sf.gg)开发者社区,是中国年轻开发者喜爱的极客社区,我们为开发者提供最纯粹的技术交流和分享平台。
目录
相关文章推荐
程序员的那些事  ·  清华大学:DeepSeek + ... ·  昨天  
程序员的那些事  ·  印度把 DeepSeek ... ·  昨天  
OSC开源社区  ·  宇树王兴兴早年创业分享引围观 ·  3 天前  
程序猿  ·  “我真的受够了Ubuntu!” ·  2 天前  
程序员的那些事  ·  成人玩偶 + ... ·  4 天前  
51好读  ›  专栏  ›  SegmentFault思否

JavaScript 解构的 5 个有趣用法

SegmentFault思否  · 公众号  · 程序员  · 2019-10-24 13:38

正文

SegmentFault 社区专栏:疯狂的技术宅
作者:Patricia Neil
翻译:疯狂的技术宅
来源:dmitripavlutin



如果你查看我的常规 JavaScript 代码,会看到到处都有解构。

读取对象属性和访问数组项是常见的操作。结构使这些操作变得更加轻松和简洁。

在本文中,除了基本用法之外,我还将会介绍在 JavaScript 中 5 种有趣的解构用法。

1、交换变量


通常交换两个变量的方法需要一个附加的临时变量。让我们看一个简单的场景:

let a = 1;
let b = 2;
let temp;

temp = a;
a = b;
b = temp;

a; // => 2
b; // => 1


temp 是保存 a 的值的临时变量。然后,为 a 分配 b 的值,最后为 b 分配 temp 的值。

解构分配使变量交换变得简单,不需要任何临时变量:

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


尽管仍会创建临时数组,但使用解构分配交换变量更为简洁。

这不是极限。你可以同时交换两个以上的变量。让我们尝试一下:

let zero = 2;
let one = 1;
let two = 0;

[zero, one, two] = [two, one, zero];

zero; // => 0
one;  // => 1
two;  // => 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 变量。如果数组在索引 0 处没有任何元素,则将分配默认值 white

但是这有更多的灵活性。如果你只想访问第二个元素,也可以这样:

const colors = [];

const [, secondColor = 'black'] = colors;

secondColor; // => 'black'


注意结构左侧的逗号:这意味着第一个元素将被忽略。从 color 数组中为索引为 1 的元素分配了 secondColor

3、不变的操作

当我开始用 React 以及后来的 Redux 时,被迫编写尊重不变性的代码。尽管一开始遇到了一些困难,但后来我看到了它的好处:单向数据流更容易处理。

不变性禁止更改对象。幸运的是,解构可以帮你轻松地以不变的方式完成某些操作。

结合使用 ... rest 操作符可以从数组的开头删除元素:


const numbers = [123];

const [, ...fooNumbers] = numbers;

fooNumbers; // => [2, 3]
numbers; // => [1, 2, 3]


解构 [, ...fooNumbers] = numbers 将创建一个新的数组 fooNumbers ,其中包含来自 numbers 的项目,除了第一项。

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' }


解构与 object rest operator 结合使用可创建一个具有 big 所有属性的新对象 small ,唯独不包含 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, donefalse };
        }
        return { donetrue };
      }
    };
  }
};

const [firstMovieTitle] = movies;
console.log(firstMovieTitle); // => 'Heat'


movies 对象通过定义 Symbol.iterator 方法来实现可迭代的协议。迭代器遍历电影的标题。

遵循可迭代协议,可以将 movies 对象结构为标题,特别是通过读取第一部电影的标题:






请到「今天看啥」查看全文