昨天学习了es6语法中解构赋值,解构赋值在声明中和函数传参提高了灵活性和便捷性,值得掌握该语法。

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

let [a,b,c] = [1,2,3];
console.log(a);    // 1
console.log(b);    // 2
console.log(typeof c);    // number
console.log(a === 1);     // true

ps:解构不成功,变量的值就等于undefined

 let [arr,foo] = [1];
 console.log(foo);    // undefined

有两种解构:
 1 完全解构,等号左边的变量和等号右边的值一一对应
 2 不完全解构,等号左边的模式,只匹配一部分的等号右边的数组

let [x, y] = [1, 2, 3];
console.log(x);  // 1
console.log(y);  // 2
let [x,[a],y] = [1,[2,3],4];
console.log(a)  // 2

数组解构赋值可以带有默认值

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

解构赋值如果有默认值,与之对应的也有值,则覆盖默认值

let [a,b=2] = [1,3];
console.log(`a的值是${a}        b的值是${b}` )     //  1      3

解构赋值中右边有undefined时,与之对应的左边会采用其默认值。若两者都是undefined,则为undefined

let [a,b=2] = [1,undefined];
console.log(`a的值是${a}        b的值是${b}` )    // 1      2  

ps:在es6的规定下,要判断两者是否相等,必须用三等===来判断。

let [a,b=2] = [1,null];
console.log(a)    // 1
console.log(null === undefined)  // false  严格模式下,null和undefined不等
console.log(b)    // null

最常见的例子就是如何将两个数值互换,一般我们常用借用第三个变量或者用加减法来进行互换,因此数组的解构赋值也可以将两个数值互换。

let x = 1;
let y = 2;
[x, y] = [y, x];
console.log(`x:${x}     y:${y}`)     // x:2     y:1

 
对象的解构
 
对象的解构与数组有一个重要的不同。数组的元素是按次序排列的,变量的取值由它的位置决定;而对象的属性没有次序,变量必须与属性同名,才能取到正确的值。如果对象解构赋值中没有找到对应的属性名,则返回undefined

let {b, a, c} = {a: 'peter', b: 'Bob'};
console.log(`a:${a}         b:${b}     c:${c}`)    // peter     Bob    undefined

如果变量名和属性名不一致,根据对象解构的内部机制:先找到同名属性,然后再赋给对应的变量(我感觉既然是自己声明变量,倒不如向上面的一样就好)。

const obj = {
     foo: 'peter',
     bar: 25
};
let {foo: name, bar: age} = obj;
console.log(`name:${name}       age:${age}`)     // name:peter       age:25

对象解构赋值的默认值情况跟数组一样。
 1 有默认值,与之对应的也有值,则覆盖默认值
 2 右边有undefined时,与之对应的左边会采用其默认值。若两者都是undefined,则为undefined
 3 右边的值是null,左边有默认值,也要返回null

ps: 当你解构对象并赋值给变量时,如果你已经声明不打算声明这些变量(亦即赋值语句前没有let、const或var关键字),会报语法错误。

{obj} = {obj: 10}    //  Uncaught SyntaxError: Unexpected token =

这是因为JavaScript语法通知解析引擎将任何以{开始的语句解析为一个块语句(例如,{console}是一个合法块语句)。解决方案是将整个表达式用一对小括号包裹:

({obj} = {obj: 10})

在对象解构赋值中,最常用的就是,函数返回值,有多个时,可以按照返回对象的形式返回。

function foo() {
  return {
    foo: 1,
    bar: 2
  };
}
let { foo, bar } = foo();

可以提取 JSON 对象中的数据

let json = {
    id: 1,
    status: 200,
    data: [123, 456]
};
let { id, status, data: number } = json;
console.log(id, status, number);  // 1, 200, [123, 456]

 
字符串解构
 
字符串解构赋值,是字符串被转换成了一个类似数组的对象

let [a,b,c,d,e,f] = 'hello';
console.log(`a:${a}    b:${b}    c:${c}    d:${d}    e:${e}   f:${f}`)    // a:h    b:e    c:l    d:l    e:o   f:undefined
console.log(typeof a)   // string

let [m,n,q,p] = 'w ord';
console.log(`m:${m}   n:${n}    q:${q}   p:${p}`)  // m:w   n:     q:o   p:r

let {length:len} = 'hello world';
console.log(len)    // 12
       
let [a='H',b,c,d,e,f='W'] = 'hello';
console.log(`a:${a}    b:${b}    c:${c}    d:${d}    e:${e}   f:${f}`)    // a:h    b:e    c:l    d:l    e:o   f:W

从上面的例子可知:
 字符串是按着顺序依次赋值的,有空格也要赋值为空格。
 左边的变量声明的个数>右边赋值的个数,那么从左往右的后面的元素赋值为undefined
 左边的变量声明的个数<右边赋值的个数,那么右边多余的则不展示。
 如果有类似数组的对象有length,可以对这个进行赋值。
 有默认值的情况下,则会覆盖默认值,如果最后一个元素在赋值中为undefined则会使用默认值

 
函数参数的解构赋值
 
函数参数传参可以是数组,对象,以及字符串等等,按照以前的规定写,会出现冗杂,乱,通过解构赋值,可以解放了函数的传参。

 function add([x, y]){
     return x + y;
 }
 console.log(add([1,2]));      // 3  

函数参数的解构赋值可以带有默认值

function move({x = 0, y = 0} = {}) {
  return [x, y];
}
console.log(move({x: 1, y: 2}));     // [1, 2]
console.log(move({x: 1}));        // [1, 0]
console.log(move({}));        // [0, 0]
console.log(move());       // [0, 0]

对应的笔记和实例,我放到了GitHub,https://github.com/sqh17/notes

有什么问题请私信或留下评论,一起加油。

参考资料:

阮一峰大大的es6标准入门:http://es6.ruanyifeng.com/