什么是解构赋值
以前,如果我们想给一个变量赋值,通常是这样(在Objective-C等语言中,现在仍然是如此):
|
|
而ES6
现在支持了类似这样的用法:
|
|
从而大大简化了变量赋值的语法,而且为诸如:Json解析、函数默认值用法提供了支持,文章最后会介绍。
JS的变量解构赋值,实际上的一种模式匹配,比如:{模式1} = {模式2},如果模式1能够部分或者完全匹配模式2,则匹配成功的模式1的部分变量就会被赋值为匹配到的值,否则赋值为undefined。这是解构赋值的核心思想,后面的各种类型的解构赋值其实都是这种思想的具体体现。
另外解构赋值,要求赋值对象,即等号右边的值,一定是一个可以遍历的结构,即符合Iterator
接口。
接下来会依次介绍以下几种用法:
- 数组的解构赋值
- 对象的解构赋值
- 字符串的解构赋值
- 数值、布尔值的解构赋值
- 函数参数的解构赋值
- 圆括号问题
在开始前,还有个关于null
和undefined
的小知识介绍下,js 中,null === undefined 是false。两者的区别在于:
- null表示”没有对象”,即该处不应该有值。
- undefined表示”缺少值”,就是此处应该有一个值,但是还没有定义
具体的可以看下阮一峰的文章:undefined与null的区别。下面的文章会用到这点。
数组的解构赋值
数组的结构赋值比较简单,我们下面通过一些不同的例子来看下:
正常结构
|
|
嵌套结构
|
|
…语句
|
|
缺省变量
|
|
解构不完全成功
|
|
另外还有两个注意点:
如果右侧不是一个可遍历的结构,则会报错,如:
|
|
使用let,const,不可以重复定义变量,如:
|
|
默认值
解构赋值是允许给变量默认值的,如果解构失败(模式匹配不上,或者赋值为undefined
),则会使用默认值。如:
|
|
在前面章节,讲了null
和undefined
,如果赋值null
,系统是不会使用默认值的,因为null
和undefined
是不严格相等的。如:
|
|
另外默认值可以引用解构赋值的其他变量,前提是这个变量已经声明了,如:
|
|
对象的解构赋值
对象和数组的重要区别就是,前者是顺序的,后者是非顺序的,所以对象的解构赋值,更加能体现模式匹配的意义。
如何理解
我们先讲回数组的解构赋值,其实可以这样理解:
|
|
a可以理解为模式1,[b,c]可以理解为模式2, d可以理解为模式3
函数可以这样写
|
|
在数组中,模式的匹配是根据,
的因为数组是有序的,而在对象中,模式匹配则是根据模式的key。比如:
|
|
我们根据模式匹配的思想,其实等号左边就是{模式1,模式2},等号右边就是{模式1:模式1值,{模式2:模式2值}},所以上述代码的完整版是:
|
|
这里我们一定要区分的就是模式名和模式实例,比如:
|
|
这里的foo是模式名,并不是变量,所以不会被赋值.
嵌套对象的注意点
有嵌套对象的时候,需要注意,如果子对象的父属性不存在,会报错,如:
|
|
这中间的流程是这样的:
|
|
已声明的变量赋值注意点
大括号的情况要注意,会被系统理解为代码块,发生错误:
|
|
在外面加上圆括号可以解决:
|
|
字符串的解构赋值
字符串在被解构赋值的时候,会被转换成类似数组的对象:
|
|
属性解构
这里要介绍个好玩的东西,解构不止能解构值,还能解构属性,因为这里用的都是.
语法,比如:
|
|
数值和布尔值的解构赋值
在数值和布尔值的情况下,等号右边会先转换成对象。
比如:
|
|
这里还是可以用属性解构:
|
|
这里的数值和布尔值的结构赋值,我目前不太了解具体的实际用法,如果读者知道,麻烦告诉我哈。
函数参数的结构赋值
这里和对象的解构赋值一模一样,不具体介绍
圆括号问题
学过编译原理的人都知道,编译原理到底有多变态,所以编译器的感受应该和我们一样(笑)。在遇到()的时候,编译器也会出现问题,所以这里有个原则:
能不适用圆括号,就不要使用
除非,满足两个条件
- 不是定义变量,而是赋值
- 不在模式部分适用
比如:
|
|
其他的都会报错
用途
解析多个值
在使用函数的时候,经常会返回多个值(js中常见,其他的还真的不常见),用解构赋值的话,语法就会非常简单:
|
|
函数的参数和默认值
|
|
这里可以节省判断入参的代码
和map结合
|
|
载入模块使用
|
|
这里的用法其实大都差不多,主要是用来简化代码,提高可读性。