一、什么是解构赋值

ES6中,通过解构赋值,可以将属性 / 值从对象 / 数组中取出,赋值给其他变量的操作就是解构赋值。

在下图上可以发现左侧和右侧都必须是数组,左侧可以定义 n 个变量,那么与之对应的右侧也需要有相应个数的变量值,我们左侧的变量从右侧取值的操作就是解构赋值。

二、数组解构

在上面的图示里可以看出来,数组解构就是从数组中提取值,只要等号两边的模式相同,左边的变量就会在右侧的数组里查找对应位置的值进行赋值操作。

数组结构的应用主要有:

*
对一维数组解构

*
对多维数组解构

*
对字符串解构

*
对...扩展运算符解构

1. 一维数组解构

传统的变量赋值是这样的:
let arr = [1,2,3];//把数组的值分别赋给下面的变量; let a = arr[0]; let b = arr[1]; let c =
arr[2]; console.log(a); // a的值为1 console.log(b); // b的值为2 console.log(c); //
c的值为3
变量的解构赋值:
let [a,b,c] = [1,2,3]; //把数组的值分别赋给下面的变量; console.log(a); // a的值为1
console.log(b); // b的值为2 console.log(c); // c的值为3
左侧是数组,右侧也是数组。

左侧的变量会根据索引,依次获取右侧数组里的值。

代码短了很多,可读性也很强,这种叫做数组的解构赋值。

一句话:按索引取值~!

*
不完全解构

当左边的模式(你可以理解为格式)与右边不完全一样的时候,那么赋值过程中,只会给模式匹配成功的部分的变量赋值。

*
没得到的值的变量,返回的就是 undefined。相当于只声明了变量,但是没赋值。

*
没有变量存储的值,就会被浪费掉。
let [a] = []; // a = undefined let [name,age,add] = ["Lily", , "Chongqing"];
console.info( name ); // Lily console.info( age ); // undefined console.info(
add ); // Chongqing let [x, , z] = [1, 2, 3]; //x=1,z=3 // 传统写法 let arr = [1,
2, 3]; let x = arr[0]; let z = arr[2];
* 左侧变量可以设定默认值
如果变量的值取到了 undefined ,那么左侧变量返回的就是默认值。否则,就是右侧设定的值。
let [name="Lily",age=18] = [ "Mouse", 20 ] ; // age = 20 let
[name="Lily",age=18] = [ "Mouse", 0 ] ; // age = 0 let [name="Lily",age=18] = [
"Mouse", NaN ] ; // age = NaN let [name="Lily",age=18] = [ "Mouse", null ] ; //
age = null let [name="Lily",age=18] = [ "Mouse" ] ; // age = 18 let
[name="Lily",age=18] = [ "Mouse" , undefined ] ; // age = 18
* 可以用来交换变量数据 let a = 1; let b = 2; [a,b] = [b,a]; console.info(a,b); // 2 1
2. 多维数组结构
let arr1 = [1,[2,3],4]; let [a1, [b1,c1,d1], e1] = arr1; console.info(
a1,b1,c1,d1,e1); // 1,2,3,undefined,4
按照索引对应就行。

如果两侧不一致:
let [a,b,c] = [1,[2,3]]; console.log(a,b,c); // 1 [2, 3] undefined
从这里可以看出,结构赋值其实就是一种模式匹配,两边模式要一致才行。

3. 字符串解构

字符串也可以这么玩,因为字符串的字符也是有索引的。在解构赋值的过程中,字符串被转换成了一个类似数组的对象。
// 证明字符串有索引 let str = "hello"; console.info( str[0] ); // h console.info(
str[1] ); // e // 字符串解构 let str = "hello"; let [a,b, , ,c] = str ;
console.info( a,b,c); // h e o
4. 拓展运算符(...)

也称为扩展运算符 ,就是三个连续的点(...)。

作用:取出参数对象中可遍历的属性,拷贝到当前对象之中。(百度出来的)

我的个人理解是:可以把数组转为数据序列。

*
函数参数
function add(x, y) { // 参数 x,y 是个数据序列,逗号隔开。 return x + y; } let numbers = [4,
10]; // 数组 add(...numbers); // 14。 把数组转为数据序列,可以作为函数的参数。
* 复制数组 // 复制数组 let arr1 = [1, 2]; let arr2 = arr1; // 数组是引用数据类型。arr1,arr2
都指向同一个数组空间。 // 一个数据改了,另一个数据也改了 arr2[0] = 2; console.info(arr1) // [2, 2] ,复制失败
// 用 ... 拓展运算符就可以复制数组 let arr1 = [1, 2]; let arr2 = [...arr1]; arr2[0] = 2 ;
console.info( arr1 ); // [1, 2] ,复制成功。arr1 不受 arr2 数据变化影响。
* 数组合并 // 传统做法 let arr = [1,2,3]; let newarr = [4, 5].concat(arr); //
用concat连接两个数组,返回一个新的数组副本 // ES6 拓展运算符 let arr = [1,2,3]; let newArr1 = [4,
5,...arr]; let newArr2 = [4, ...arr , 5]; console.info( newArr1 ); // [4, 5, 1,
2, 3] console.info( newArr2 ); // [4, 1, 2, 3, 5]
* 与数组结构一起用
用于生成数组
let [first, ...rest] = [1, 2, 3, 4, 5]; console.info( first ); // 1
console.info( rest ); // [2, 3, 4, 5]
如果将扩展运算符用于数组赋值,只能放在参数的最后一位,否则会报错。
let [...rest, last] = [1, 2, 3, 4, 5]; // 报错 let [first, ...rest, last] = [1,
2, 3, 4, 5]; // 报错
* 将字符串转为真正的数组 let str = "hello"; let arr = [...str]; console.info( arr ); //
["h", "e", "l", "l", "o"]
三、对象解构

按照属性来进行解构赋值,如果解构不成功,变量的值等于 undefined。对象解构可以指定默认值。

1. 和数组解构的对比

*
数组的元素是按次序排列的,变量的取值由它的位置决定;

*
模式匹配,两边都必须是 Object 对象。

*
而对象的属性没有次序,变量必须与属性同名,才能取到正确的值。

// 对象的解构赋值,跟顺序没有关系 let {age, name } = { name:"Tom", age:18 };
console.info(age,name); // 18 , Tom let { age:b, name:a } = { nam e:"Tom",
age:18 }; console.info( b, a ); // 18 , Tom
左右属性名不一致,会得到 undefined。
let {age, nameZ } = { name:"Tom", age:18 }; console.info(age,nameZ); // 18 ,
undefined let { age:b, nameZ:a } = { name:"Tom", age:18 }; console.info( b, a
); // 18 , undefined
对象解构语句不是以变量声明关键字(如var,let或const)开头,则需要将语句包裹在括号中。 否则会报错。
({ a, b } = { a:100, b:200 } ); // good let { a, b } = { a:100, b:200 } ; //
good let a , b ; { a, b } = { a:100, b:200 } ; // 报错
2. 对象解构默认值
// 变量的非 undefined 的值可以取到 let { name, age = 28 } = { name:"Tom", age:18 };
console.info( name, age ); // Tom , 18 // 变量取到了 undefined ,则返回默认值 let { name,
age = 28 } = { name:"Tom" }; console.info( name, age ); // Tom , 28 let {name:
a = "Tom", age: b = 28} = { name :"Lily"}; console.info( a, b ); // Lily, 28 //
右侧一个值都没有 let {name: a = "Tom", age: b = 28} = {}; console.info( a, b ); // Tom,
28
3. 对象作为函数参数

Object 对象可以作为函数参数。
let addFun = function( obj ){ let sum = obj.a + obj.b ; console.info( sum );
}; addFun({ a:100, b:200 }); // 300
为了设置 a ,b 默认值。利用对象解构,设置形参:
// 实参和形参会进行解构操作。 let addFun = function( { a=100, b=100 } ){ let sum = a + b ;
console.info( sum ); }; addFun({ a:100, b:200 }); // 300。a ,100 ; b,200
addFun({ a:50 }); // 150。a,50; b 被省略,取默认值 100 。 addFun({ }); // 200。a , b 均取默认值
addFun(); // Cannot read property 'a' of undefined
上面代码只使用了对象的解构赋值默认值,没有使用函数参数的默认值。只有当函数 addFun 的参数是一个对象时,变量 a 和 b 才会通过解构赋值生成。

如果函数 addFun 调用时没提供参数,变量 a 和 b 就不会生成,从而报错。
addFun(); // 报错。Uncaught TypeError: Cannot read property 'a' of undefined
相当于在执行代码
{ a=100, b=100 } = undefined ;
试图对 undefined 进行对象结构,会报错。

通过提供函数参数的默认值,就可以避免这种情况。
let addFun = function( { a=100, b=100 } = {} ){ let sum = a + b ;
console.info( sum ); }; addFun( ); // 200。
参数默认值是 {} 。{} 会解构给 a,b 赋值。a,b 解构的值都是 undefined,所以取 a,b 均会获取解构的默认值 100。

四、对非对象进行解构

如果解构的值为 null、undefined,会得到一个类型错误提示。

如果你的值为数字、布尔值、字符串,会得到一个 undefined。

如果等号左侧的变量名为 Object.prototype 上的方法名称时,返回的就是方法实例。
let {a} = null ; // 报错 let {a} = undefined ; // 报错 let { age:a } = undefined ;
// 报错 let {a} = 13 ; // a = undefined let { toString } = 123 ; // toString() {
[native code] }
 

技术
©2019-2020 Toolsou All rights reserved,
ajax get请求中文参数乱码解决央视:Tiktok打官司表明了维权的态度和决心vue-countTo 操作大全Element-UI二次封装实现TreeSelect 树形下拉选择组件PowerShell中使用WebClient 下载文件并获取下载进度判断当前对象是不是数组的4种方式ELementUI select多选下拉框获取选中项的全部属性SpringBoot JpaRepository 数据库增删改查指定位置输出字符串(详细解析)SpringMVC框架中在controller层获取自定义配置文件的属性值