第七章:关于解构赋值其他方面

其他的解构赋值

字符串的解构赋值

字符串也可以结构赋值,此时字符串被转换成了一个类数组对象。

1
2
3
4
5
6
const [a,b,c,d,e] = 'hello'
a//'h'
b//'e'
c//'l'
d//'l'
e//'o'

类数组对象都有length属性,因此还可以对这个属性解构赋值。

1
2
let {length: len} = 'hello'
//len=5

数值与布尔值的解构赋值

  1. 解构赋值时,如果等号右边是数值或者布尔值,则会先转为对象。

    1
    2
    3
    4
    5
    let {toString: s} = 123
    s === Number.prototype.toString // true
    let {toString: s} = true
    s === Boolean.prototype.toString //true
  2. 解构赋值的规则是,只要等号右边的值不是对象,就先将其转为对像,由于undefined和null无法转为对象,所以对他们进行解构赋值赋值都会报错。

函数参数的解构赋值

  1. 函数参数的解构赋值

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    function add([x,y]){
    return x + y
    }
    add(1,2)//3
    ```
    2. add的参数实际上不是一个数组,而是通过解构得到的变量x,y
    3. 函数参数的解构也可以使用默认值。
    ```javascript
    function move({x=0,y=0} = {}){ return [x,y]}
    move({x:3,y:8})//[3,8]
    move({y:8})//[0,8]
    move()//[0,0]
    move({})//[0,0]
  2. 默认值的变型

    1
    2
    3
    4
    5
    6
    7
    function move({x,y}={x:0,y:0}){
    return [x,y]
    }
    move({x:3,y:8})//[3,8]
    move({x:3})//[3,undefined]
    move({})//[undefined,undefined]
    move()//[0,0]

    上面的代码是为函数move的参数指定默认值,而不是为了变量x,y指定默认值,所以会得与前一种写法不同的结果。

  3. undefined会出发函数参数的默认值

    1
    2
    [1,undefined,3].map((x = 'yes')=>x)
    //[1,'yes',3]

关于圆括号!

上节我们说了,圆括号是为了解决对象解构赋值的时候,花括号存在于行首这样的情况出现。

那么什么时候我们是不能使用圆括号呢??

  1. 变量声明语句中,模式不能使用圆括号

    1
    2
    3
    let [(a)] = [1]
    let {x:(c)} = {}
    let {o:(p:p)} = {o:{p:2}}//全部报错
  2. 函数参数重,模式不能带有圆括号

    1
    function f([(z)]){ return z}//报错
  3. 不能将整个模式或嵌套模式中的一层放入圆括号里

    1
    2
    ({p:a}) = {p:42}
    ([a]) = [5]//全部报错

可以使用圆括号的情况

可以使用圆括号的情况只有一种:赋值语句的非模式部分可以使用圆括号

1
2
[(b)] = [3]
({p:{b}}) = {} //正确

解释:1.他们都是赋值语句,而不是声明语句
2.他们的圆括号都不属于模式的一部分

解构赋值的用途

  1. 变换变量的值

    1
    [x,y] = [y,x]
  2. 从函数返回多个值

    1
    2
    3
    4
    5
    6
    7
    function exmple(){
    return [1,2,3]
    }
    let [a,b,c] = exmple()
    a//1
    b//2
    c//3
    1
    2
    3
    4
    5
    function exmple(){
    return {foo:1,bar:2}
    }
    let {foo,bar} = exmple()
    //{foo:1,bar:2}
  3. 函数参数的定义
    结构赋值可以方便的将一组参数与变量名对应起来

    • 有序值

      1
      2
      3
      function f([x,y,z]){ ... }
      f([1,2,3])
      //x:1,y:2,z:3
    • 无序值

      1
      2
      3
      function f({x,y,z}){ ... }
      f({x:1,z:3,y:2})
      //{x:1,y:2,z:3}
  4. 提取Json数据
    解构赋值对提取Json対值中的数据尤其有用。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    var jsonData = {
    id: 42,
    status: 'ok',
    data: [867,5309]
    }
    var {id,status,data:number} = jsonData
    console.log(id,status,number)
    //42,'ok',[867,5309]
  5. 函数参数的默认值

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    jQuery.ajax = function(url,{
    async = true,
    beforesend = function(){ ... },
    cache = true,
    complete = function(){ ... },
    crossDomain = false,
    global = true,
    //...more config
    }){
    //do stuff
    }

指定参数的默认值,就避免了在函数体内部再写var foo = config.foo || default.foo这样的语句。

6.遍历Map的结构

Map结构原生支持Iterator接口,配合变量的结构赋值,获取键名和键值就非常方便。

1
2
3
4
5
6
7
8
9
var map = new Map()
map.set('first', 'hello')
map.set('second','world')
for(let [key,value] of map){
console.log(key + 'is' + value)
}
//first is hello
//second is world

如果只是想获取键名或者键值的话,可以写成下面那样。
//获取键名

1
for(let [key] of map){ ... }

//获取键值

1
for(let [value] of map){ ...}

  1. 输入模块的指定方法
    加载模块时,往往需要指定输入那些方法,解构赋值是得输入语句非常清晰
    1
    const { SourceMapConsumer,SourceNode } = require('source-map')