关于JS解构的5种有趣用法


Posted in Javascript onSeptember 05, 2019

前言

原文标题:5 Interesting Uses of JavaScript Destructuring

原文链接:dmitripavlutin.com/5-interesti…

定期回顾我写的JS代码,我发现解构运算无处不在。

获取对象的属性和访问数组内容是都是很常用的操作。而解构运算使得这些操作变得非常简单明了。

在这篇文章中,我将会讲解JS解构不同于常见用法的五种使用技巧。

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。

即使这种方式仍然创建了一个临时数组,但是解构赋值对于交换变量的值仍然是非常高效简单的方式。

这种方式并没有什么限制。你还可以同时交互更多的变量值,比如:

let zero = 2;
let one = 1;
let two = 0;
[zero, one, two] = [two, one, zero];
zero; //=> 0
one; //=> 1
two; //=> 2

你可以交换任意数量的变量值,只是两个变量值的交换的情况更加常见。

2. 访问数组

有一个数组,这个数组有可能是空的。有一种需求是访问任意位置数组元素,如果这个位置为空,则返回一个默认值。
通常情况下有的人可能会使用数组的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的位置上没有任何元素(注:为undefined时即认为为空),white将作为默认值赋值给firstColor。
数组解构是非常灵活的,如果你只想访问数组的第二个元素,方法如下所示:

const colors = [];
const [, secondColor = "black"] = colors;
secondColor;  //=> "black"

在解构表达式的左边写一个逗号:意味着数组的第一个元素被忽略掉。colors数组下标为1的元素被解构赋值给了变量secondColor。

3. 不可变操作

从我开始使用React,到后来的Redux,我被迫开始写一些遵循不可变原则的代码。刚开始的时候确实有点不适应,不过后来我就意识到了这种方式的好处:它使得处理单向数据流更加容易。

不可变原则禁止修改对象。幸运的是,解构可以帮助你在遵循不可变原则的同时完成这些操作。

将解构与展开运算符(rest operator)结合使用来移除数组的第一个元素:

const numbers = [1,2,3];
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" }

上述方法将解构与对象展开运算符结合起来使用,创建了一个新的对象small,这个新对象包含big对象除了foo属性之外的所有属性。

4. 解构可迭代的值

在前面几部分内容中,都是解构的数组。实际上解构运算是可以用于所有的可迭代对象的。

许多原生的基础类型和对象都是可迭代的,例如数组,类数组,字符串,set集合和map集合。

例如,你可以把字符串解构成单个字符:

const str = "cheese";
const [firstChar = ""] = str;
firstChar;  //=> 'c'

当然解构不仅仅限于原生可迭代的那几种类型。解构可以被用于所有实现了迭代接口(iterable protocol)的对象。
如下所示,movies包含一个movie对象列表。我们想要解构movies对象的时候,可以获取到电影的title这个字符串。实现这个操作首先需要自定义一个迭代器:

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方法实现了一个迭代器。这个迭代器可以迭代所有电影的title属性。

我们在movies对象上遵循了迭代接口实现,从而实现了通过解构movies来获取到标题,比如我们获取第一个电影的标题:const [firstMovieTitle] = movies;

解构用法的上限就是没有上限。

5. 解构动态属性

在我的经验中,解构一个对象的属性要远比解构一个数组的情况更多。

解构对象看起来非常的简单:

const movie = { title: "Heat" };
const { title } = movie;
title;  //=> Heat

const { title } = movie;创建了一个变量title,然后把movie.title的值赋值给了这个变量。

当我第一次了解到对象解构的时候,有一点令我惊讶的是你并不需要预先知道属性的静态名称。你可以通过动态属性名来解构一个对象。

为了了解动态解构的工作原理,我们来写一个打招呼的函数作为例子:

function greet( obj, nameProp ) {
  const { [nameProp]: name="Unknow" } = obj;
  return `Hello, ${name}!`;
}
greet({ name: "Batman" }, "name");  //=>  Hello, Batman!
greet( {}, "name" );  //=>  Hello, Unknow!

greet()被调用时需要传递两个参数,一个是对象,一个是属性名称。

在greet()函数内部,解构表达式const { [nameProp]: name="Unknow" } = obj;使用中括号[nameProp]读取动态属性的名称。name变量接收动态属性的值。

更好的做法就是你可以指定一个默认的值Unknow以防属性不存在的情况。

6. 总结

解构可以帮助你更方便快捷的访问对象属性和数组元素。

除了基本用法之外,数组解构还可以方便的交换变量,访问数组元素,做一些遵循不可变原则的操作。

JavaScript提供了更多的可能性,因为你可以通过扩展迭代器实现自定义的解构逻辑。

好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对三水点靠木的支持。

Javascript 相关文章推荐
use jscript List Installed Software
Jun 11 Javascript
jQuery each()方法的使用方法
Mar 18 Javascript
js操作textarea 常用方法总结
Dec 03 Javascript
编写js扩展方法判断一个数组中是否包含某个元素
Nov 08 Javascript
JS小功能(button选择颜色)简单实例
Nov 29 Javascript
jQuery中:header选择器用法实例
Dec 29 Javascript
jQuery晃动层特效实现方法
Mar 09 Javascript
JavaScript实现星星等级评价功能
Mar 22 Javascript
详解windows下vue-cli及webpack 构建网站(三)使用组件
Jun 17 Javascript
基于javaScript的this指向总结
Jul 22 Javascript
Webpack中publicPath路径问题详解
May 03 Javascript
通过js随机函数Math.random实现乱序
May 19 Javascript
vue draggable resizable gorkys与v-chart使用与总结
Sep 05 #Javascript
JavaScript获取某一天所在的星期
Sep 05 #Javascript
layui table设置某一行的字体颜色方法
Sep 05 #Javascript
微信小程序HTTP接口请求封装代码实例
Sep 05 #Javascript
layui table去掉右侧滑动条的实现方法
Sep 05 #Javascript
微信小程序下拉加载和上拉刷新两种实现方法详解
Sep 05 #Javascript
layui动态加载多表头的实例
Sep 05 #Javascript
You might like
PHP数组与对象之间使用递归实现转换的方法
2015/06/24 PHP
php创建桌面快捷方式实现方法
2015/12/31 PHP
PHP中substr_count()函数获取子字符串出现次数的方法
2016/01/07 PHP
简单谈谈PHP中的include、include_once、require以及require_once语句
2016/04/23 PHP
PHP判断JSON对象是否存在的方法(推荐)
2016/07/06 PHP
php 删除指定文件夹的实例讲解
2017/07/25 PHP
PHP排序二叉树基本功能实现方法示例
2018/05/26 PHP
Laravel5.5 视图 - 创建视图和数据传递示例
2019/10/21 PHP
jQuery maxlength文本字数限制插件
2010/04/16 Javascript
javascript预览上传图片发现的问题的解决方法
2010/11/25 Javascript
js修改table中Td的值(定义td的双击事件)
2013/01/10 Javascript
当json键为数字时的取值方法解析
2013/11/15 Javascript
js判断60秒以及倒计时示例代码
2014/01/24 Javascript
自动完成的搜索框javascript实现
2016/02/26 Javascript
js代码实现下拉菜单【推荐】
2016/12/15 Javascript
nodejs 子进程正确的打开方式
2017/07/03 NodeJs
浅谈Vue.js中的v-on(事件处理)
2017/09/05 Javascript
基于Vue单文件组件详解
2017/09/15 Javascript
小程序云开发如何实现图片上传及发表文字
2019/05/17 Javascript
Element-Ui组件 NavMenu 导航菜单的具体使用
2019/10/24 Javascript
jquery将信息遍历到界面上实例代码
2020/01/21 jQuery
javascript实现简易计算器功能
2020/09/23 Javascript
基于python 处理中文路径的终极解决方法
2018/04/12 Python
深入浅析Python获取对象信息的函数type()、isinstance()、dir()
2018/09/17 Python
python实现静态服务器
2019/09/05 Python
python argparser的具体使用
2019/11/10 Python
python二分法查找算法实现方法【递归与非递归】
2019/12/06 Python
python 怎样进行内存管理
2020/11/10 Python
康拓普公司Java笔面试
2016/09/23 面试题
公司联欢晚会主持词
2014/03/22 职场文书
电气工程及其自动化专业求职信
2014/06/23 职场文书
清洁工工作总结
2015/08/11 职场文书
2019财务转正述职报告
2019/06/27 职场文书
关于感恩的作文
2019/08/26 职场文书
深入解析MySQL索引数据结构
2021/10/16 MySQL
分享Python获取本机IP地址的几种方法
2022/03/17 Python