目录
1.解构赋值理论
2.数组的解构赋值详解
1.数组解构赋值的理解:
2.解构默认值(有特殊情况bug)
3.解构嵌套数组
4.相同"模式"的不完全解构
3.对象的解构赋值
1.基本:对象的属性没有次序,(重点:变量必须与属性同名),才能取到正确的值。
2.赋值给新变量名 (其中简写很重要)
3.对象的不完全解构(对象解构也有的bug)
4.数组和对象的嵌套解构
5.对象解构的错误写法
4.函数参数的解构赋值
1.解构对象类型参数
2.解构数组类型参数
3.为参数设定默认值
4.注意点:数组注重下标相匹配(在乎次序),对象注重相同对象名相匹配(不在乎次序)
5.解构的用途
1. 交换变量值
2.从函数返回多个值
3.提取JSON数据(使用解构最多的)
语法是一种 Javascript 表达式。通过解构赋值,可以将属性/值从对象/数组中取出,赋值给其他变量。
也可以说:解析数据源,然后按照数据模型进行取值(左侧变量可以多变,只要总体的数据模型没变,就能取到右侧数据),再赋值给变量,也可以称为声明变量的高级写法。
解析:按照数据模型取出数据源中的数据
赋值:然后赋值给模型变量。
语法结构:变量修饰符 数据模型 = 数据源;
特点:
解构赋值是对赋值运算符的扩展。
是一种针对数组或者对象进行模式匹配,然后对其中的变量进行赋值。
在代码书写上简洁且易读,语义更加清晰明了;也方便了复杂对象中数据字段获取。
解构赋值只包括:数组解构和对象解构
形式:
//数组解构
let [a, b, c] = [1, 2, 3];
//对象解构
let { foo, bar } = { bar: 'bbb' , foo: 'aaa'};
说明:在解构赋值语法中,"="左侧的叫做数据模型,="右侧的叫做数据源。
其中:[a, b, c] ,叫做数组的数据模型,{foo, bar}叫做对象的数据模型。
下面对于数组的解构赋值和对象的解构赋值详解
数组解构是非常简单简洁的,在赋值表达式的左侧使用数组字面量,数组字面量中的每个变量名称映射为解构数组的相同索引项
且:我们在获取获取数组内的元素时,大多是通过下标的方式arr[0]
,这种方式也确实方便,但针对特定的情况时,解构会大大提高你的效率
一行代码搞定上面的:
如果解构取出的值是undefined
,可以取设置默认值,没设置就是取undefined
分析:这里给a,b分别设置的默认值为5和7,因为 左侧数组字面量中的变量b,在右侧的解构数组中没有对应的索引值。会得到undefined,但b本身设置了默认值,所以为7
也就是:
有对应索引值取对应索引值,无对应索引值取默认值,无默认值取undefined。
对应索引值优先
索引值其次
最后是undefined
特殊情况1:
但这里有个bug,如果对应索引值为undefined,也设置了默认值,那是应该取undefined,还是默认值?按照上面的是取对应索引值,这里对应索引值是undefined,但结果呢?
结果b取的默认值2,而不是对应索引值, 所以这是一个特殊情况。
特殊情况2:
如果默认值是一个表达式,那么这个表达式是惰性求值的,即只有在用到的时候,才会求值(想到函数要在调用的时候才能用到)。
分析:因为x有对应的索引值1,能取到1,所以f()根本就没运行,所以 不要看到f(),就说函数调用,要根据实际代码情况分析。
如果把let [x = f()] = [1]; 换成let [x = f()] = [ ]; 最后运行结果就是 "aaa",因为x没对应索引值,所以x就是默认值,而默认值是f(),函数运行结果为 "aaa"。所以x就是 "aaa"
注意点:
- 数组的解构是根据它的位置(模式)对应的
- 解构操作允许有默认值,但一定是已经声明的。
- 如果等号的右边不是数组(或者严格地说,不是可遍历的结构)那么将会报错
解构嵌套数组,就是模式匹配,只要赋值符号"="两边的层级结构相同,就可以拿到对应位置的值
模式相同,但变量没有完全相同时:
注意点:
1.解构赋值是将最小单位的字符设置为变量
分析: let {name,sons:[s1]} = obj; 这段代码是 将name 和 s1 设置为变量(name和s1为最小单位),而不是把 sons 也设置为变量。是通过sons找到obj的sons成员,是一个数组,取下标为0 的元素{name:'jack',age:1},并将其保存到变量s1中。
2.解构赋值 本质是是一个定义变量的过程:"="左侧的数据模型中的变量,不能是同名的
怎么避免同一个变量呢? 把其中一个变量设置为另一个变量名不就好了么
利用对象赋值给新变量的方法(下面有说)
对象的解构与数组有一个重要的不同。数组的元素是按次序排列的,变量的取值由它的位置决定;而对象的属性没有次序,(重点:变量必须与属性同名),才能取到正确的值。
当使用对象解构时可以改变变量的名称或者也可以说成是如果变量名与属性名不一致时:
分析:let { age: foo, B: bar } = { age: 22, B: true }; 是对象数据模型(对象字面量)中 age,B在右侧源数据中找到对应的数据,然后把右侧对应的数据赋值给 左侧 的变量foo,bar
注意点:age和B不是变量,所以打印出会报错,真正的变量是foo和bar,age和B只是与右侧数据源的一个对应。
所以可以得到:
let { foo, bar } = { foo: "aaa", bar: "bbb" };就是
let { foo:foo, bar:bar} = { foo: "aaa", bar: "bbb" };的简写形式
如果赋值给新的对象名,这里我们可以给这个新的变量名提供一个默认值,如果没有解构它(右侧中没找到对应的属性名),就会自动使用默认值
分析:给新的变量名strong和slim设置默认值 22/21. girl: slim = 21 在右侧数据源中没找到对应的属性名,就会使用默认值21
分析:变量y,在右侧数据源中能找到对应的属性名,变量x,没找到,且x也没设置默认值,所以会取到undefined
对象解构和数组解构都有的bug,设置了默认值,但右侧对应数据源值为undefined,此时应该取默认值还是取undefined?
结果是取默认值,这是一个bug,记住就行 。
总结:一般情况下,有对应属性名的值(非undefined)就取该值,右侧数据源没有对应属性名就取设置的默认值,也没对应属性名也没设置默认值,就取undefined。特殊:右侧对应属性名的值为undefined时,取设置的默认值,若没设置,才取undefined。
万变不离其宗,不管怎么嵌套,都是在对象和数组解构的基础上进行,只要数据模型没变,改变参数名,最后得到的结果都不会变。比如: const [, , { name }] = props;改为const [a,b, { name }] = props;,参数虽然变了,但是最后结果却没变。
因为JavaScript引擎会将{boy}
理解为一个代码块,从而产生语法错误,我们要避免将大括号写在行首,避免JavaScript将其解释为代码块
正确写法:
正确写法将整个解构赋值语句放在一个圆括号(代表是一个整体)里,就可以正确执行了
利用解构优化函数调用时中场景:
//上面这样写,可以是可以,显得比较繁琐 学了ES6中的解构赋值后 下面这样写
设定默认值,可以避免许多拿不到数据的情况
一般已知交换两个变量的方法:1.设置一个临时变量 2.利用异或 3.利用数组的解构赋值
1.设置一个临时变量
2.利用异或
3.利用数组的解构赋值
函数只能返回一个值,如果要返回多个值,我们只能将这些值放置数组或对象里返回,当我们有了解构赋值后,从对象或数组里取出这些值就很soeasy
举例:
企业级数据的使用方法:
1.存入一个js文件里面,并声明一个变量来保存这些数据
2.在html文件中,引入外部js文件
3.将数据打印到控制台中,再利用解构赋值进行取数据
注:本文引用了一些其它博主的作品,它们写得很好,可以去看看
http://t.csdn.cn/pJPmL
http://t.csdn.cn/ToSA1