解构赋值的意思:允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构
数组的解构赋值
大多数变量赋值都是单独进行的
let a = 10
let b = 10
上面这样写法就单独进行简单的赋值,那么数组解构赋值如何去写,请看下面的例子
let [a] = 10
上面这样写会报错,左边[a]为匹配项,右边10为赋值项,如果右边不是数组,或不是可遍历的结构就会报错
------------------
下面这样就不会报错,匹配项可以匹配到,而且这也算是单独赋值
let [a] = [10]
console.log(a) // 将会得到10
结构赋值的优点就是多个赋值,结构化赋值,下面的b会得到undefined,因为匹配项匹配到的赋值为undefined未定义
let [a,b] = [10]
console.log(a) // 10
console.log(b) // undefined
那我们来看看结构化多一点的赋值
let [a,[b,c,[d]],[e,f],g,[[h]]] = [1,[2,3,[4]],[5,6],7,[[8]]]
console.log(a,b,c,d,e,f,g,h) // 1,2,3,4,5,6,7,8
如果去掉[[8]]的二维数组,变为一维数组会怎样
let [a,[b,c,[d]],[e,f],g,[[h]]] = [1,[2,3,[4]],[5,6],7,[8]]
console.log(a,b,c,d,e,f,g,h) // 报错
那我们来看看数组解构赋值的默认值是如何定义的呢?
let [arr = 3] = []
console.log(arr) // 3
来看看下面这一组
let [arr1 = 1,arr2 = 2,arr3=3] = []
console.log(arr1,arr2,arr3) // 1,2,3
记住数组解构赋值不管你有没有默认值,右边只要匹配到并且有值都会覆盖左边的默认值
let [arr1 = 1,arr2 = 2,arr3=3] = [3,2,1]
console.log(arr1,arr2,arr3) // 3,2,1
但是有一种类型除外不会右边的不会覆盖左边的默认值,undefined(只有它)
let [a = 3] = [undefined]
console.log(a) // 3
对象的解构赋值
对象的结构赋值和数组的不太一样,对象是对属性进行匹配的,而数组是按顺序匹配的
下面我们来看看对象解构赋值如何来写
let {re, ty} = {re: 1, ty: 2}
console.log(re,ty) // 1,2
下面这个例子obj会报错是因为obj是匹配项用来匹配右边对象的属性key,而左边的baz才是变量
let {obj: baz} = {obj: 'baz'}
console.log(baz) // baz
console.log(obj) // 报错
我们来试着写对象解构化的解构赋值
let obj = {
a: {
b: [1],
c: {
c1: 'c1',
c2: 'c2',
c3: true
}
}
}
let {a, a: {b,c: {c1,c2,c3}}} = obj
console.log(a) // 解构出的结果
{
b: [1],
c: {
c1: 'c1',
c2: 'c2',
c3: true
}
}
会得到[1],这就是对象解构赋值的原因,打印里面的属性都会得到值而且不会报错
console.log(b)
我们再来看看对象解构赋值默认值
右边的值永远覆盖左边的默认值,除却undefind
let {init = 4} = {init: 5}
console.log(init) //5
字符串,数值布尔,函数解构赋值
字符串
我理解的啊就是字符串会被分割成数组,然后一一对应,感觉和数组解构赋值差不多
let [a,b,c,d,e,f] = 'qwert'
console.log(a,b,c,d,e,f) // q,w,e,r,t,undefined
我们还可以获取字符串的长度,但是匹配属性必须为length,否则会报错
let {length : len} = '哈哈哈哈哈哈';
len // 6
数值布尔
我看官方是给了两个例子,数值和布尔解构都会将之转化为对象,软老师的解释就是数值和布尔值的包装对象都有toString属性,那我们来打印一下Number.prototype和Boolean.prototype果然两个里面都有toString的方法,而且还有一个valueOf方法,我们来试试
let {toString: s} = 123;
console.log(s) // 这会是一个toString方法
let {valueOf: s3} = true
s3 === Boolean.prototype.valueOf // true
函数
我们这里会得到12,其实这和上边的数组解构赋值和对象解构赋值一样,只要你能匹配到就可以解构
function add({a,b}) {
return a+b
}
console.log(add({a:10,b:2}))
function add({hh:[x, y],c}){
return x + y+c;
}
console.log(add({hh:[1,2],c: 1})) //4
圆括号
变量声明语句中,不能带有圆括号。
let [(x)] = [3]
let ({a}) = {a: 3}
函数参数中,模式不能带有圆括号(函数属于声明变量)
赋值语句中,不能将整个模式,或嵌套模式中的一层,放在圆括号之中。
整个模式我理解的意思就是呢就是把左边的匹配模式包起来了
([b]) = [123]
这种情况就是包裹一部分而且把模式包裹起来了
[({ p: a }), { x: c }] = [{}, {}];
那么正确的使用呢,就是例如下面这样,有对象的话一定要包裹变量,或是全部包裹起来
[{ p: (a) }, { x: c }] = [{}, {}];
[{ p: (a) }, { x: (c) }] = [{}, {}];
[({ p: a }, { x: c })] = [({}, {})];
([{ p: a }, { x: c }] = [{}, {}]);
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。