重学ES6 | 解构赋值

819 阅读6分钟

前言

做为一个前端,经常要处理来自返回的数据,解构是ES6的语法糖,就像一个黑魔法师一样,将处理赋值复杂的数据变得简单明了。

MDN中定义:解构赋值语法是一种 Javascript 表达式。通过解构赋值, 可以将属性/值从对象/数组中取出,赋值给其他变量。

基础用法

来看一段代码,叙述了ES5时期取变量值和使用解构赋值的区别

	//在以前我们要取一个数组或者对象里的值可能是这样的
		let arr = [1, 2];
		let a = arr[1];
		let b = arr[2];
		console.log(a, b); //1,2

		let obj = {
			c: 3,
			d: 4
		}
		let c = obj.c;
		let d = obj.d;
		console.log(c, d) //3,4


		//现在使用简单解构
		//数组
		let [a, b] = [1, 2];
		console.log(a, b); //1 2
		//对象
		let {
			c,
			d
		} = {
			c: 3,
			d: 4
		}
		console.log(c, d); //3 4

上述代码就是简单的解构,等号左右两边按照相同的格式书写,可以提炼出相应的值,极大的缩短的代码的书写时间使其更简洁易读。接下来具体看一看到底什么是解构赋值

分类

解构赋值按个人理解大致分为以下几类
  • 数组解构
  • 对象解构
  • 嵌套解构
  • 参数解构

数组解构

解构可以对数组进行赋值

简单的数组解构赋值:
//现在使用简单数组解构
let [a, b] = [1, 2];
console.log(a, b); //1 2
当你对数组里的某些值不感兴趣的时候:

这里可以使用,(逗号)作为占位符,表明占据一个位置

let [a,,b,c] = [1,2,3,4,5];
console.log(a,b,c)
//打印的结果为
//1,3,4

let [c,,,d,e] = [1,2,3,4]
console.log(c,d,e)
//打印的结果为
//1,4,undefined

由上述例子可以看出,逗号可以当占位符,变量的顺序与数组的顺序一一对应,当检索不到时会自动复制为undefined。例如本例中的e赋值为undefiend ``

也可以使用扩展运算符(...)来参与解构
let [a,...b] = [1,2,3,4]
console.log(a,...b);
//此处打印
//1   [2,3,4]

注意:如果剩余元素右侧有逗号,会抛出 SyntaxError,因为剩余元素必须是数组的最后一个元素

var [a, ...b,] = [1, 2, 3];
// SyntaxError: rest element may not have a trailing comma
解构默认值

为了防止从数组中提取出一个undefined,我们也可以给解构的变量赋上默认值,当变量匹配不到时使用默认值

let [a,b=1] = [1]
//打印结果为
//a的值是1b的值也是1

对象解构

除了数组之外,对象也是可以进行解构的,我们来看一看吧

简单的对象解构赋值
//例子1
let {a,b} = {a:1,b:2}
//此时b的值为1,b的值为2
重命名变量

有时候我们从对象中拿的值,并不是原封不动的就直接提取的,我们可能需要改名,这个时候解构也可以做到。

例子1的代码其实等同于

let {a:a.b:b} = {a:1,b:2}

由此可知":"的右侧是新变量的变量名,左侧用来匹配位置,在例子1中是简写,例如这个特性我们就可以提取名字不同于对象中属性名的变量

let {a:r,b:f} = {a:1,b:2}
//此时打印的结果:
//r的值为1,f的值为2,进行了重命名
默认值

跟数组解构一样,为了防止提取undefiend的变量,也可以设置默认值

let {a=1,b} = {b:2}
//此时a的值为默认值1,b的值为2
又要默认值,又要重命名时

此时我们可以这样写

let {a:e,c:d=3} = {a:2}
//此时e的值为2,d的值为默认值3

函数参数解构

传统方式,没有用到解构的时候:
let obj = {
   c:10,
   d:11
}
function test(obj){
  return obj.c+obj.d
}		

在传统的函数传参过程中,如果我们有多个参数的话,为了简便,通常会这样做,用一个对象来承载所有的参数。它的obj参数是一个对象类型;但是只是查看函数的声明部分,我们无法得知这一点,这就会给使用者带来不便:使用者无法确定第三个参数是一个对象类型,无法确定这个对象里面需要哪些属性。 以上的问题我们可以通过使用解构参数来得到解决

当使用解构参数的时候:

下面例子使用解构参数来处理这个问题,可以看到,参数需要什么字段在函数声明部分可以一清二楚的看到

function test({c,d}){
	//函数体
}
//调用
test({c:10,d:11})

注意:解构参数不能不传值 当我们不给解构参数传值时,js代码是会报错的,为了避免这个问题我们给解构参数设置默认值,如下:

给解构参数设置默认值

当我们不使用解构参数时,设置默认值是这样的

let obj = {
	c:10,
	d:11
}
function test(obj){
	let tem = obj.c || null;
	let tem1 = obj.d || null;
	return obj.c+obj.d
}

当我们使用解构,是这样写的

let obj = {
	c:10,
	d:11
}
function test({c,d}={}){
	//函数体
}
使用解构赋值来处理这个多参数问题

如下图的例子所示

let obj = {
	c:10,
	d:11
}
function test({c,d} = {}){
	//函数体
}
test()

如上面的例子,使用了默认值之后即使不传参也不会报错了

给解构参数的每一项赋值

我们还可以给解构参数的每一项赋值

let obj = {
	c:10,
	d:11
}
function test({c=10,d=11} = {}){
	//函数体
}
test()

如上述例子,使用=号赋默认值就好

嵌套解构

简单的解构就是如上述那样的简单,但是后台返回的数据,往往都是很复杂的,我们来拿一个后台的json来举例子,复杂的数据应该怎么处理

let res = {
	code: 200,
	data: [
		{
			name: "Juejin",
			info: '1',
			children: {
				msg: '子数据'
			}
		}
	]
}
//解构
let { 
	  code,
	  data:[
		{ 
		  name,
		  info, 
		  children:{msg} 
		}
	  ]
} = res
console.log(code, name, info, msg)

基本的准则就是保持等号左右两边的结构构一致

函数的打印结果为: 上面代码的解构注释字样后的第三行,我们初始化的变量为name和info,而不是data,这一点要特别注意。data只是用来指明name和info的父节点。下面部分的children和msg亦是如此

嵌套对象的解构的语法就是:从原对象的最外层变量定位,一直到需要取值的那一层,每层之间用冒号:隔开,变量在冒号的右边

小提示:解构的各种基础用法,设置默认值,重命名也是可以在嵌套时使用的