关于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 相关文章推荐
六款帮助你实现惊艳视差滚动效果的jQuery插件
Sep 14 Javascript
js实现连续英文字符自动换行兼容ie6 ie7和firefox
Sep 06 Javascript
JS+CSS实现的经典圆角下拉菜单效果代码
Oct 21 Javascript
浅析JavaScript 调试方法和技巧
Oct 22 Javascript
js友好的时间返回函数
Aug 24 Javascript
实现一个简单的vue无限加载指令方法
Jan 10 Javascript
Swiper实现轮播图效果
Jul 03 Javascript
Express使用html模板的详细代码
Sep 18 Javascript
微信小程序中setInterval的使用方法
Sep 29 Javascript
解决Vue开发中对话框被遮罩层挡住的问题
Nov 26 Javascript
IDEA安装vue插件图文详解
Sep 26 Javascript
Vue+Node实现的商城用户管理功能示例
Dec 23 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作的文本留言本的例子(五)
2006/10/09 PHP
PHP中防止SQL注入攻击和XSS攻击的两个简单方法
2010/04/15 PHP
php截取指定2个字符之间字符串的方法
2015/04/15 PHP
PHP的Yii框架中Model模型的学习教程
2016/03/29 PHP
YII2自动登录Cookie总是失效的解决方法
2017/06/28 PHP
php实现生成带二维码图片并强制下载功能
2018/02/24 PHP
在视频前插入广告
2006/11/20 Javascript
javascript下判断一个对象是否具有指定名称的属性的的代码
2010/01/11 Javascript
Jquery替换已存在于element上的event的方法
2010/03/09 Javascript
JavaScript 开发规范要求(图文并茂)
2010/06/11 Javascript
Javascript/Jquery——简单定时器的多种实现方法
2013/07/03 Javascript
jQuery 中DOM 操作详解
2015/01/13 Javascript
JavaScript实现Java中StringBuffer的方法
2015/02/09 Javascript
JS实现具备延时功能的滑动门菜单效果
2015/09/17 Javascript
javascript的几种继承方法介绍
2016/03/22 Javascript
Vue.js实战之通过监听滚动事件实现动态锚点
2017/04/04 Javascript
学习JS中的DOM节点以及操作
2018/04/30 Javascript
微信小程序实现城市列表选择
2018/06/05 Javascript
Nodejs实现爬虫抓取数据实例解析
2018/07/05 NodeJs
值得收藏的八个常用的js正则表达式
2018/10/19 Javascript
layui form表单提交后实现自动刷新
2019/10/25 Javascript
JS数据类型判断的几种常用方法
2020/07/07 Javascript
js节流防抖应用场景,以及在vue中节流防抖的具体实现操作
2020/09/21 Javascript
pycharm下打开、执行并调试scrapy爬虫程序的方法
2017/11/29 Python
python3连接MySQL数据库实例详解
2018/05/24 Python
Python列表解析配合if else的方法
2018/06/23 Python
浅述python中深浅拷贝原理
2018/09/18 Python
python 检查是否为中文字符串的方法
2018/12/28 Python
如何使用Python自动控制windows桌面
2019/07/11 Python
Django中的cookie和session
2019/08/27 Python
python IP地址转整数
2020/11/20 Python
学生打架检讨书大全
2014/01/23 职场文书
倡议书格式模板
2014/05/13 职场文书
普通党员个人剖析材料
2014/10/08 职场文书
向女朋友道歉的话
2015/01/20 职场文书
Ajax异步刷新功能及简单案例
2021/11/20 Javascript