定期回顾我写的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提供了更多的可能性,因为你可以通过扩展迭代器实现自定义的解构逻辑。


补充:

1. 数组解构

在js中数组的结构是相当的灵活,但是有一个原则是不能打破的,结构时中括号不能省略,不能像python中那样直接进行不带中括号的结构,这是因为js中的逗号运算符的原因。

  1. 变量个数和数组元素个数相同的解构:
var arr = ['tom', 'jeery', 'jacky', 'doinb', 'clearlove8'];
let [a, b, c, d, e] = arr;
console.log(a, b, c, d, e);
输出结果:tom jeery jacky doinb clearlove8

变量和数组元素一一对应很好理解。

  1. 变量个数比数组元素个数少的解构:
var arr = ['tom', 'jeery', 'jacky', 'doinb', 'clearlove8'];
let [a, b] = arr;
console.log(a, b);
输出结果:tom jeery

变量个数比数组元素个数少一样不会出错,只会拿到前两个变量,而在python中这样是会报错的。

  1. 变量个数比数组元素个数多的解构:
var arr = ['tom', 'jeery', 'jacky', 'doinb', 'clearlove8'];
let [a, b, c, d, e, f, g, h, i] = arr;
console.log(a, b, c, d, e, f, g, h, i);
输出结果:tom jeery jacky doinb clearlove8 undefined undefined undefined undefined

变量个数比数组元素个数多的解构依旧不会报错,只是多出的变量没有拿到值而已。

  1. 使用丢弃变量进行解构:
var arr = ['tom', 'jeery', 'jacky', 'doinb', 'clearlove8'];
let [a, , , d] = arr;
console.log(a, d);
输出结果:tom doinb

我们可以看到,在解构的时候使用,进行占位,用标识符接收我们真正需要的元素。

  1. 使用可变变量进行解构:
var arr = ['tom', 'jeery', 'jacky', 'doinb', 'clearlove8'];
let [a, b, ...c] = arr;
console.log(a, b);
console.log(c);
输出结果:tom jeery[ 'jacky', 'doinb', 'clearlove8' ]

可以看到,我们使用一个可变变量…c进行接收后面的剩余元素,只需要拿到我们想要的a、b或者想要的c数组。

  1. 使用缺省值进行解构:
var arr = ['tom', 'jeery', 'jacky', 'doinb', 'clearlove8'];
let [a, b, c=100, d, e=200, f=300] = arr;
console.log(a, b, c, d, e, f);
输出结果:tom jeery jacky doinb clearlove8 300

a, b, c, d, e虽然有的有缺省值,但是因为能够解构得到值,它们的值都被更新为解构得到的值了,而f变量没有解构得到值,只能使用自身的缺省值。

  1. 总结:解构的时候,变量从左到右和元素对齐,可变参数放到最右边。能对应到数据就返回数据,对应不到数据的返回默认值,如果没有默认值返回undefined,把前面5中方法结合使用,我们发现js中的数组解构是相当的灵活。

2. 对象解构

同样,像数组解构那样,对象的解构也需要相同类型的括号,对象结构使用大括号{}。

  1. 简单对象解构:
const obj = {a:100,b:200,c:300}var {x, y, z} = obj;
console.log(x, y, z);
输出结果:undefined undefined undefinedvar {a, b, c} = obj;
console.log(a, b, c);
输出结果:100 200 300

从这个例子可以看出,对象的解构所用的变量要和对象的属性名一样才能拿到相应的值。

  1. 对象解构同时重命名:
const obj = {a:100,b:200,c:300}var {a:x, b:y, c:z} = obj;
console.log(x, y, z);
输出结果:100 200 300console.log(a, b, c);  // 报错  a is not defined

从这个例子可以看出,对象解构虽然要使用相应的名称才可以拿到值,但是我们可以为其进行重命名,从例子上分析出,js会使用a, b, c到对象上取值,取到值之后赋值给x, y, z,这样通过x, y, z进行使用相应的值,a, b, c则未定义。

  1. 复杂解构:
var data = {a:100,b:[{c:200,d:[],a:300},{c:1200,d:[1],a:300},],c:500
}var {a:m, b:[{a:n}, {a:n1}]} = data;
console.log(m, n, n1);

这个复杂例子一般我们是用不到的,但是可以帮助我们理解解构。

JS解构的5种有趣用法相关推荐

  1. JS(解构) 之数组和对象中提取数据总结

    解构含义 解构功能含义:从复杂数据类型中(数组或对象)中提取数据的过程. JS(解构) 之数组 从数组中提取首个元素 方式一:基于数组下标提取元素 const names = ['zzg', 'zcx ...

  2. 解构给默认值_5个 JS 解构有趣的用途

    1. 交换变量 通常交换两个变量的方法需要一个额外的临时变量,来看看例子: let a = 1; let b = 2; let temp; temp = a; a = b; b = temp; a; ...

  3. JS解构赋值:数组解构和对象解构

    一种为变量赋值的新语法,一次可以为多个变量赋值. 分成两种情况: 数组解构 let [变量的集合] = [正常的数组] 举例说明: let [x, y, z] = [10, 16, 21]; 上述代码 ...

  4. JS解构和 ... 运算符

    1. 数组解构 使用方括号[] 1.1 交换变量 let a = 1; let b = 2; let c = 3; [a, b, c] = [c, b, a]; console.log(a); // ...

  5. 【javascript】js解构赋值中使用别名

    let person = {name:"沉默小管",age:18 } //js的解构,把name别名成myName,之后就可以使用myName替换name let {name:my ...

  6. 对象解构 - 记一种哔了狗了的代码样式

    下面两段代码效果是一样的 ({a: a1,b: b1,} = c) a1= c.a; b1= c.b; 吐槽一下 我真哔了狗了,一个简单的赋值还炫尼美的样式,真没看出来第一段代码比第二段优越在哪里?简 ...

  7. JS 高级(七)ES6解构、class、promise

    目录 ES6: (ECMAScript第六个版本) 1. 解构(destruct) 2. class 3. Promise ES6: (ECMAScript第六个版本) 1. 解构(destruct) ...

  8. JS 语法糖 0 —— 解构

    文章目录 1.数组解构 1.1 简介 1.2 完全解构 1.3 不完全解构 1.4 数组解构的条件 1.5 默认值 2.对象解构 2.1 简介 2.2 解构对象方法 2.3 默认值 2.4 注意点 3 ...

  9. ES6 解构赋值详解

    解构赋值是对赋值运算符的扩展,可以将属性/值从对象/数组中取出,赋值给其他变量. 一.数组的解构赋值 1.基本用法 只要等号两边的模式相同,左边的变量就会被赋予对应的值. let [a, [[b], ...

最新文章

  1. 人人都能搞懂的AI(四)- AI对社会的影响
  2. 运维人员的补丁盛宴 四月修复微软Adobe漏洞合计过百!
  3. solve Ax+By+C=0
  4. 2017寒假练习题解 第四周 2.6-2.12
  5. linux学习——大话linux网络
  6. 如何设置电脑自动锁屏_工信部重要提醒:赶紧设置这个密码!手机丢时也不怕损失!...
  7. 求10 翻译c语言,求助:谁能帮我翻译下最基础的C语言,我是新手,谢谢了!
  8. 那些能沉淀自己的人,将会成为最后的赢家
  9. linux 统计 程序运行时间
  10. 查看一个目录是否已经mount --bind
  11. 清理SharePoint 2010的SQL Server 2008 R2日志数据库的方法
  12. Honeywell 扫描枪安装
  13. TimePicker使用全解
  14. java 穷举 排列组合_穷举排列组合列表
  15. c语言搜索答案什么软件比较好,学C语言用什么最好?
  16. [Ubuntu] Ubuntu16.04+win10+联想Y7000+显卡+WIFI 装机成功
  17. the little scheme Y-combinator
  18. python字典一键多值如何遍历_[宜配屋]听图阁
  19. 如何使用云服务器进行系统设置,云服务器怎么设置管理员
  20. Dota2 AI 简易开发教程(二)——英雄出装及其相关功能

热门文章

  1. Java代码生成手写笔记
  2. 全卷积网络FCN的缺陷
  3. 追MM和23中设计模式(来自网络)
  4. 6.18! 当当网推出购书优惠活动满400减230!有效优惠码更新
  5. Zookeeper watch机制原理
  6. HarmonyOS 真香,请叫我首席体验官!
  7. Python小白学习笔记六 (面向对象 1 )
  8. BZOJ 1142 POI2009 Tab Hash
  9. Win10如何禁用Windows Defender
  10. 烽火通信测试工程师校招一面面经