解构
解构是一种打破数据结构,将其拆分为更小部分的过程。
ES5及早期版本,从对象和数组中获取特定数据并赋值给变量,实现可能如下。
这样如果提取更多变量,则需要重复编写类似的代码来为变量赋值。解构简化了获取数据的过程。
对象解构
对象解构的语法形式是在一个赋值操作左边放置一个对象字面量
node.type
的值赋值给变量type
。
使用
var
、let
或const
解构声明变量,必须要提供等号右侧的值。如var { type, name }
,则会抛出错误。右侧的值为null
和undefined
也会报错,因为读取null
和undefined
的属性都会出发运行错误。
- 解构赋值
可以用在变量赋值时使用解构语法,如在定义变量后,修改他们的值。123456789let node = {type: 'Identifier',name: 'foo'},type = 'Literal',name = 5;({ type, name } = node);console.log(type); //'Identifier'console.log(name); //'foo'
一定要用括号包裹结构赋值语句,JavaScript引擎将一对开放的大括号视为一个代码块,代码块不允许出现在赋值语句的左侧,添加小括号其转化为一个表达式。
- 默认值
使用解构赋值表达式时,如果指定的变量名称在对象中不存在,那么这个变量会被赋值为undefined
。123456let node = {type: 'Identifier',name: 'foo'};let { type, name, value } = node;console.log(value); //undefined
当指定属性不存在的时候,可以定义一个默认值,和函数默认参数一样。
- 为非同名变量赋值
上面解构赋值使用的都是与对象属性同名的变量,如node.type
的值赋值给了变量type
,可以使用不同命名的变量。1234567let node = {type: 'Identifier',name: 'foo'};let { type: localType, name: localName } = node;console.log(localType); //'Identifier'console.log(localName); //'foo'
这种语法与原来的对象字面量的语法相悖,这里是名称在冒号右边。使用其他变量名进行赋值时,也可以添加默认值,在变量名后添加等号和默认值即可。
- 嵌套对象解构
解构嵌套对象与对象字面量类似,可以将更深层级对象拆解以获取想要的值。12345678910111213141516let node = {type: 'Identifier',name: 'foo',loc: {start: {line: 1,column: 1},end: {line: 1,column: 4}}}let { loc: { start } } = node;console.log(start); //{ line: 1, column: 1 }
嵌套对象解构中,冒号前的标识符都代表在对象中的检索位置,右侧为被赋值的变量名。如果冒号后是花括号,则意味着获取的值在更深的层级中。同样也可以使用与对象属性名不同的变量名。
数组解构
使用数组字面量且解构操作全部在数组内完成。通过值在数组中的位置进行选取,且可以将其存储在任意变量中。这个过程中,不影响数组本身。
在解构模式中,也可以只提取制定数组中的值,使用逗号做为占位符,想要获取数组某个位置的值,指定变量名,其他用逗号占位即可。
- 解构赋值
在变量赋值也是可以使用数组解构,但是不需要使用小括号。1234567let colors = ['red', 'green', 'blue'],firstColor = 'black',secondColor = 'purple';[firstColor, secondColor] = colors;console.log(firstColor); //'red'console.log(secondColor); //'green'
数组解构中,有个独特的用例:交换两个变量的值。
赋值语句左侧事一个解构模式,右侧是一个为交换过程创建的临时数组字面量。代码执行过程,将临时数组解构,把b
和a
的值复制到左侧数组的前两个位置,最终变量交换了它们的值。
同对象解构赋值一样,右侧表达式的值不能为
null
或undefined
默认值
可以在数组解构赋值表达式中为数组中的任意位置添加默认值,当指定位置的的值不存在或者其值为undefined
时,使用默认值。1234let colors = ['red'];let [firstColor, secondColor='blue'] = colors;console.log(firstColor); //'red'console.log(secondColor); //'blue'嵌套数组解构
嵌套数组解构和嵌套对象解构类似,在原有的解构模式中,插入另一个解构模式。12345let colors = ['red', ['green', 'lighitgreen'], 'blue'];let [firstColor, [secondColor]] = colors;console.log(firstColor); //'red'console.log(secondColor); //'green'不定元素
在数组解构中,可以通过...
语法将数组中的其余元素赋值给一个特定的变量。123456let colors = ['red', 'green', 'blue'];let [firstColor, ...restColors] = colors;console.log(firstColor); //'red'console.log(restColors); //[ 'green', 'blue' ]
还可以通过不定元素的语法实现复制一个数组的功能。
混合解构
可以混合使用对象解构和数组解构来创建更多复杂的表达式。
解构模式中的loc
和range
仅代表它们在node
对象中所处的位置。