关于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 相关文章推荐
js几个不错的函数 $$()
Oct 09 Javascript
jQuery中index()的用法分析
Sep 05 Javascript
用C/C++来实现 Node.js 的模块(二)
Sep 24 Javascript
基于JQuery和CSS3实现仿Apple TV海报背景视觉差特效源码分享
Sep 21 Javascript
jQuery使用serialize()表单序列化时出现中文乱码问题的解决办法
Jul 27 Javascript
javascript如何创建对象
Aug 29 Javascript
d3.js实现简单的网络拓扑图实例代码
Nov 06 Javascript
Vue导出页面为PDF格式的实现思路
Jul 31 Javascript
详解jQuery获取特殊属性的值以及设置内容
Nov 14 jQuery
ES6 let和const定义变量与常量的应用实例分析
Jun 27 Javascript
VueQuillEditor富文本上传图片(非base64)
Jun 03 Javascript
express异步函数异常捕获示例详解
Nov 30 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
浅析Yii中使用RBAC的完全指南(用户角色权限控制)
2013/06/20 PHP
php缩小png图片不损失透明色的解决方法
2013/12/25 PHP
php输入流php://input使用浅析
2014/09/02 PHP
PHP使用mongoclient简单操作mongodb数据库示例
2019/02/08 PHP
Thinkphp5.0框架视图view的模板布局用法分析
2019/10/12 PHP
关于Jquery操作Cookie取值错误的解决方法
2013/08/26 Javascript
indexOf 和 lastIndexOf 使用示例介绍
2014/09/02 Javascript
轻松创建nodejs服务器(8):非阻塞是如何实现的
2014/12/18 NodeJs
jQuery中append()方法用法实例
2015/01/08 Javascript
JS实现统计复选框选中个数并提示确定与取消的方法
2015/07/01 Javascript
以jQuery中$.Deferred对象为例讲解promise对象是如何处理异步问题
2015/11/13 Javascript
JavaScript中的原始值和复杂值
2016/01/07 Javascript
jQuery实现简单滚动动画效果
2016/04/07 Javascript
html5 canvas 详细使用教程
2017/01/20 Javascript
JavaScript门面模式详解
2017/10/19 Javascript
JS的Ajax与后端交互数据的实例
2018/08/08 Javascript
angular2实现统一的http请求头方法
2018/08/13 Javascript
微信小程序实现的点击按钮 弹出底部上拉菜单功能示例
2018/12/20 Javascript
JS pushlet XMLAdapter适配器用法案例解析
2020/10/16 Javascript
Python使用lxml模块和Requests模块抓取HTML页面的教程
2016/05/16 Python
浅谈python类属性的访问、设置和删除方法
2016/07/25 Python
利用python操作SQLite数据库及文件操作详解
2017/09/22 Python
Python中利用xpath解析HTML的方法
2018/05/14 Python
Python3.5运算符操作实例详解
2019/04/25 Python
python启动应用程序和终止应用程序的方法
2019/06/28 Python
Python 实现取多维数组第n维的前几位
2019/11/26 Python
利用PyTorch实现VGG16教程
2020/06/24 Python
html5+svg学习指南之SVG基础知识
2014/12/17 HTML / CSS
使用canvas压缩图片大小的方法示例
2019/08/02 HTML / CSS
MATCHESFASHION澳大利亚/亚太地区:英国时尚奢侈品电商
2020/01/14 全球购物
计算机毕业大学生推荐信
2013/12/01 职场文书
小学教师国培感言
2014/02/08 职场文书
2014年度思想工作总结
2014/11/27 职场文书
OpenCV图像变换之傅里叶变换的一些应用
2021/07/26 Python
WINDOWS 64位 下安装配置mysql8.0.25最详细的教程
2022/03/22 MySQL
Python使用openpyxl模块处理Excel文件
2022/06/05 Python