ES6之表达式结构(Destructuring)

表达式结构(Destructuring)

  目录:

  • 表达式结构Destructuring
    • 语法
      • 使用对象作为返回载体带有标签的多返回值
      • 使用数组作为返回载体
    • 使用场景
      • promise 与模式匹配
      • 变量值交换 Swap
    • 高级用法
      • 解构别名
      • 无法匹配的缺省值
      • 深层匹配
    • 配合其他新特性


语法

使用对象作为返回载体(带有标签的多返回值)

  用法:{ arg1, arg2 } = { arg1: value1, arg2: value2}

function getState(){
    // …
    return {
        error: null,
        logined: true,
        user: { /* … */ },
        // …
    }
}
const { error, logined, user } = getState();
if(error) { /* … */ }


使用数组作为返回载体

  用法:[ arg1, arg2 ] = [ value1, value2]

const [foo, bar] = [1, 2];
console.log(foo, bar); //1 2



  如果希望跳过数组中某些元素,可以通过空开一个元素的方式实现:

// 用法:[ arg1, , arg2 ] = [ value1, value2, value3]

const [foo, , bar] = [1, 2, 3];
console.log(foo, bar); //1 3



  如果希望能在获取指定位置的元素以外,也可以不定项地获取后续的元素,那么可以用 … 语句来实现:

// 用法:[ arg1, arg2, ...rest ] = [ value1, value2, value3, value4]

const [a, b, ...rest] = [1, 2, 3, 4, 5];
console.log(a, b);  // 1 2
console.log(rest);  // [3, 4, 5]

使用数组作为返回载体与使用对象作为返回载体的区别是:数组需要让被赋予的变量(或常量)名按照数组的顺序获得值


使用场景

promise 与模式匹配

  在文档约定完备的情况下,我们可以使用数组作为载体,好处在于执行 Promise.resolve 方法时的语法较为简单:

function fetchData(){
    return new Promise((resolve, reject) => {
        // ..
        resolve([ 'foo', 'bar' ]);
    })
}

fetchData()
    .then(([value1, value2]) => {
        console.log(value1, value2);  // foo bar
    });

fetchData()
    .then( [value1, value2]  => {   // SyntaxError
        // ...
    });

需要注意的是,如果在 promise.then 方法中传入的是一个带有解构参数的箭头函数时,解构参数外必须有一个括号包裹,否则会抛出语法错误。


  如果参数过多但在某个场景下并不需要全部参数,或者文档约定不完善的情况下,使用对象作为传递载体更佳。

function fetchData(){
    return new Promise((resolve, reject) => {
        // ..
        resolve({
            code: 200,
            message: 'OK',
            data: [ 'foo', 'bar', /* ...*/ ]
        });
    })
}

fetchData()
    .then(({ data}) => console.log(data));  // foo bar ...


变量值交换 Swap

function swap(a, b){
    var tmp = a;
    a = b;
    b = tmp;
}

let foo = 1;
let bar = 2;

// Before
console.log(foo, bar);   // 1 2

// Swap
[foo, bar] = [bar, foo];

// After Swap

console.log(foo, bar);  // 2 1

高级用法

解构别名

  如果在一个使用了对象作为多返回值载体的函数中,我们需要获取其中的某个返回值,但是却不想使用其中的属性名作为新的变量名(或常量名),那么就可以使用别名来获取相应的返回值,只需要在原来的返回值名称后面加上” : x “即可,其中 x 为希望使用的变量名。

function fetchData(){
    return {
        respone: ['foo', 'bar', /* … */]
    }
}

const { respone: data} = fetchData();
console.log(data);  // foo bar …


无法匹配的缺省值

  如果在模式匹配中,存在无法匹配的值(载体对象中不存在相应的值或目标参数所对应下标超出了载体数组的下标范围),默认情况下会获得 undefined

// Object
const {foo, bar} = {foo: 1};
console.log(foo, bar);  // 1 undefined

// Array
const [a, b, c] = [1, 2];
console.log(a, b, c);   //1 2 undefined



  为了避免这种情况发生,我们可以为无法匹配的值设置默认值

const {foo = 1} = { bar: 1};
console.log(foo);  // 1

const [a, b = 2] = [1];
console.log(a, b);  // 1 2

深层匹配

// Object
const {a, b: {c}} = {a:1, b: {c: 2}};
console.log(a, c);  //1 2

// Array in Object
const {d, e: [f]} = {d: 1, e: [2, 3]};
console.log(d, f);  //1 2

// Object in Array
const [g, {h}] = [1, {h: 2}];
console.log(g, h);  //1 2

// Array in Array
const [i, [j]] = [1, [2, 3]];
console.log(i, j);  //1 2

配合其他新特性

const arr = ['Mike', 'Peter', 'Ben', 'William', 'John'];
for(const [index, item] of arr.entries()){
    console.log(index, item);
    if(item.match(/^W/)) break;  // Break!
}
//0 "Mike"
//1 "Peter"
//2 "Ben"
//3 "William"

forEach 无法像 for、 while 等循环语句一样被 break 等控制语句终止,所以可以使用 for-of 循环语法。

你可能感兴趣的:(ES6)