关于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插件总结
Jan 20 Javascript
JQuery球队选择实例
May 18 Javascript
js+css实现文字散开重组动画特效代码分享
Aug 21 Javascript
在页面中输出当前客户端时间javascript实例代码
Mar 02 Javascript
全面了解addEventListener和on的区别
Jul 14 Javascript
jQuery页面弹出框实现文件上传
Feb 09 Javascript
微信JSAPI Ticket接口签名详解
Jun 28 Javascript
浅谈js中的this问题
Aug 31 Javascript
对于Javascript 执行上下文的全面了解
Sep 05 Javascript
使用pkg打包Node.js应用的方法步骤
Oct 19 Javascript
vue使用微信JS-SDK实现分享功能
Aug 23 Javascript
解决Vue的文本编辑器 vue-quill-editor 小图标样式排布错乱问题
Aug 03 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用mysql_insert_id()函数获得刚插入数据或当前发布文章的ID
2016/11/25 PHP
php二维码生成以及下载实现
2017/09/28 PHP
基于Laravel 5.2 regex验证的正确写法
2019/09/29 PHP
PHP7 错误处理机制修改
2021/03/09 PHP
基于jQuery的自动完成插件
2011/02/03 Javascript
JavaScript获取FCK编辑器信息的具体方法
2013/07/12 Javascript
创建js对象和js类的方法汇总
2014/12/24 Javascript
JavaScript 面向对象与原型
2015/04/10 Javascript
javascript继承的六大模式小结
2015/04/13 Javascript
详细分析使用AngularJS编程中提交表单的方式
2015/06/19 Javascript
使用JavaScript的AngularJS库编写hello world的方法
2015/06/23 Javascript
javascript运动效果实例总结(放大缩小、滑动淡入、滚动)
2016/01/08 Javascript
Bootstrap滚动监听(Scrollspy)插件详解
2016/04/26 Javascript
JavaScript实现打印星型金字塔功能实例分析
2017/09/27 Javascript
python监控文件并且发送告警邮件
2018/06/21 Python
深入学习python多线程与GIL
2019/08/26 Python
python是否适合网页编程详解
2019/10/04 Python
如何使用python代码操作git代码
2020/02/29 Python
简单掌握CSS3将文字描边及填充文字颜色的方法
2016/03/07 HTML / CSS
基于CSS3 animation动画属性实现轮播图效果
2017/09/12 HTML / CSS
Lee牛仔裤澳大利亚官网:美国著名牛仔裤品牌
2017/09/02 全球购物
英国行业制服供应商:Alexandra
2019/09/14 全球购物
Intersport西班牙:在线体育商店
2019/11/06 全球购物
Belstaff英国官方在线商店:Belstaff.co.uk
2021/02/09 全球购物
英国著名的美容护肤和护发产品购物网站:Lookfantastic
2020/11/23 全球购物
请写出 BOOL flag 与"零值"比较的 if 语句
2016/02/29 面试题
50道外企软件测试面试题
2014/08/18 面试题
后勤工作职责
2013/12/22 职场文书
人民教师的自我评价分享
2014/02/21 职场文书
艺术学院毕业生自我评价
2014/03/02 职场文书
安全生产责任书范本
2014/04/15 职场文书
乡镇挂职心得体会
2014/09/04 职场文书
仲裁协议书
2014/09/26 职场文书
停电放假通知
2015/04/14 职场文书
2015年科普工作总结
2015/07/23 职场文书
班主任培训研修日志
2015/11/13 职场文书