1、什么是解构赋值?
ES6 新增了对象解构语法,简单地说,对象解构就是使用与对象匹配的结构来实现将数组中的值或对象的属性取出,赋值给其他变量。解构赋值在处理后台接口返回数据中使用的非常广泛,下面是两个解构赋值的基础例子:
arduino
// 对象
const obj = { a: 1, b: 2 };
const { a, b } = obj; // a=1, b=2
// 数组
const arr = ["red", "yellow", "green"];
const [one, two, three] = arr; // one="red", two="yellow", three="green"
console.log(one)
obj
和arr
本质上同属于对象,二者解构的语法形式上的区别仅在于花括号和中括号,但实际上数组解构是从数组中按照顺序提取元素,并将它们分配给变量。而对象解构从对象中根据属性名提取值,并将它们分配给变量。数组解构基于位置,而对象解构基于属性名,在对象中查找匹配的属性名。
所以,以上例子可以理解为从对象obj
中解构出属性名为a
和b
的属性值,再通过const
方式声明同名变量进行承接赋值,另外一个数组例子也是类似的,只不过解构赋值时是对应的索引位置。
2、设置解构默认值
每个解构属性都可以有一个默认值,并且默认值可以是一个表达式
当属性不存在或值为undefined
时,将使用默认值
而属性值为null
时,则不使用默认值而是使用null
ini
const [a = 1] = []; // a is 1
const { b = 2 } = { b: undefined }; // b is 2
const { c = 2 } = { c: null }; // c is null
const { d = console.log('d is undefined') } = { d: undefined }; // d is undefined
3、解构变量的赋值/重命名
实际开发中,通常我们从数据中直接解构赋值获取的变量名不一定是我们想要的,所以可以采取加一个冒号
进行重新命名的方式,这种重命名方式本质是将解构出来的变量重新赋值给一个新的变量。
css
// 从对象 o 中获取名为 p 的属性,并将其赋值给名为 foo 的局部变量。
const obj = { p: 1, q: 2 }
const { p: foo } = obj
console.log(foo); // 1
// 解构对象中变量a的值赋值给默认值为10的局部变量A,解构对象中变量b的值赋值给默认值为10的局部变量B
const { a: A = 10, b: B = 5 } = { a: 3 };
console.log(A); // 3
console.log(B); // 5
4、多层嵌套解构与解构数组中指定索引
如1中所述,对象解构就是使用与对象匹配的结构来实现将数组中的值或对象的属性取出,所以对于多层结构,我们也要在左侧构造出相同的结构,那下面这个例子中,我们要如何通过解构获取到变量cover
呢?
css
const data = {
code: "000000",
list: [
{
id: '12345',
listUrls: [
{ cover: 'https://xxx.com', url: 'https://yyy.com' },
]
},
],
}
虽然看着有点复杂,但只需关注两点..
1、套了多少层分别是什么?
2、是对象的话关注属性值;是数组的话关注索引位置
kotlin
// 1、首先建立同样的数据结构,三层对象两层数组
const {[{[{}]}]} = data
// 2、然后再关注对象结构中有用到的属性名,无需关注位置先填到对象结构中去,注意一点,因为是多层结构所以需要通过向下赋值才能把解构出来的值传递下去,所以不要漏掉冒号
const { list: [{ listUrls: [{ cover }] }] } = data
// 3、最后检查数组结构,关注所用的索引和我们的有没有对应上,发现:list数组中用到的是0号位,listUrls中有用到的也是0号位,而在我们写的解构结构中的数组内,正好也都是使用的0号位,那么就不需要做什么改动了,直接打印看下结果!
console.log(cover); // https://xxx.com
基于上面例子,会想到如果不是解构0号位置的变量又该怎么做?可以用空来占位要忽略的位置,举例如下:
ini
const props = [
{ id: 1, name: "Fizz" },
{ id: 2, name: "Buzz" },
{ id: 3, name: "FizzBuzz" },
];
const [, , { name }] = props;
console.log(name); // "FizzBuzz"
那么把之前的例子做一下小调整,同样去解构那条不为空的cover
css
const data = {
code: "200",
list: [
{
id: '',
listUrls: [
{ cover: '', url: '' },
]
},
{
id: '12345',
listUrls: [
{ cover: '', url: '' },
{ cover: '', url: '' },
{ cover: 'https://xxx.com', url: 'https://yyy.com' },
]
},
],
}
发现相比之前两个数组分别从0号索引位置变成了1号和2号位置,那么相比之前在数组里面多加下逗号忽略不要的位置即可:
kotlin
const { list: [, { listUrls: [, , { cover }] }] } = data // https://xxx.com
如果不了解,可能乍一看const { list: [, { listUrls: [, , { cover }] }] } = data
会有点懵,这是解构吗?这解的什么鬼,但实际了解了之后发现其实不难。
5、思考
在实际开发中,对于很多层嵌套结构的数据,比如后台透传一些算法数据时,结构会套的很深,然而其实很少使用解构去做,如果使用也只做必然存在的外面一层或两层中的变量,除了多层嵌套解构复杂的原因外,更实际的原因在于当使用多层解构时,如果中间变量有缺失,会报错并中止代码执行,所以可选链(?.)这种方式会用的更多一些 ~
如果对解构赋值还有感兴趣的小伙伴可以移步mdn官网做进一步了解:developer.mozilla.org/zh-CN/docs/...)