解构赋值的意思:允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构

数组的解构赋值

 大多数变量赋值都是单独进行的
 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 }] = [{}, {}]);

me_zhazha
288 声望6 粉丝