es6解构赋值

es6允许按照一定模式,从数组和对象中提取值,对变量进行赋值,被称之为解构(Destructuring)

之前变量赋值

let a = 1;
let b = 2;
let c = 3;

es6可以这么写

let [a,b,c] = [1,2,3];
//上面代码表示,可以从数组中提取值,按照对应位置,对变量赋值

默认值

解构赋值允许指定默认值

let [f = true] = [];
console.log(f);//true
let [x,y = 'b'] = ['a'];
console.log(x,y);//a b
let [m,n = 'b'] = ['a',undefined];
console.log(m,n);//a b

只有当一个数组成员严格等于(===)undefined,默认值才会生效

如果一个数组成员是null,默认值就不会生效(因为null不严格等于undefined

let [x=1] = [undefined];
let [z=1] = [null];
console.log(x);//1
console.log(z);//null

默认值可以引用解构赋值的其他变量,但该变量必须已经声明。(否则报错)

let [x = 1,y = x] = [];
let [a = 1,b = a] = [3];
let [m = 5,n = m] = [1,2];
let [e = i,i = 1] = [];
console.log(x,y);//1 1
console.log(a,b);//3 3
console.log(m,n);//1 2
console.log(e,i);//ReferenceError: i is not defined报错
//最后一个e用i做默认值时,i还没有声明 所以报错

数组解构赋值

如果要解构数组,那么声明变量时候两边都得是数组

当然数组中变量也可以默认赋值

当等号右边值没有时候会走默认,否则走左边的值

如果解构不成功变量值会是undefined

/*
规则:
先从右往左赋值,如果右边都为undefined,
此时就看左边的数组变量,数组变量执行的顺序为从左边到右边
如果数组变量的右边使用了数组变量的左边的变量,那么是能够赋值的。
*/
let colors = [ "red", "green", "blue" ];
let [ firstColor, secondColor ] = colors;
console.log(firstColor); // "red"
console.log(secondColor); // "green"

在解构模式中,也可以直接省略元素,只为感兴趣的元素提供变量名

let colors = [ "red", "green", "blue" ];
let [ , , thirdColor ] = colors;
console.log(thirdColor); // "blue"

使用es6调换位置

 var a = 10;
 var b = 5;
 var [a,b] = [b,a];
 console.log(a,b);  //5,10

右边为undefined,而左边有默认值,最后输出默认值

var [b=5,a] = [,b];
 console.log(b);    //5

解构不成功变量的值会为undefined

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

等号左边只匹配一部分等号右边一部分的数组,这种也可以解构成功

(值比变量多的话可以,变量比值多就不可以了)

let [a,b,c,d,e] = [1,2,3,4];
console.log(e);//undefined
console.log(d);//4

对象解构赋值

对象字面量的语法形式是在一个赋值操作符左边放置一个对象字面量

let {name,age,sex} = {name:'小明',age:'20',sex:'男'};
console.log(name,age,sex); //小明 20 男

解构的值,必须要为对象的key值,不然会为undefined

let {key1,key2,key3:k3} = obj
k3就代表key3 ,当写了:k3时,key3就失效则报错

对象解构与数组不同的是:

  • 数组解构按顺序排列,变量取值由他的位置决定
  • 对象解构变量需要与属性名同名,解构的值是对象的key值

等号左边变量的次序,与右边同名属性次序不一致也可以取到值

let {b,f} = {f:'我的',b:163};
console.log(f,b);//我的163

与数组一样,解构也可以用于嵌套结构的对象

 let obj = {
    p:[ //这里p是模式不是变量,所以不会被赋值
        'hello',
        {y:'world'}
    ]
};
console.log(obj.p[0] +  obj.p[1].y);//hello world


//如果p也要作为变量赋值可以这么写

let obj = {
  p: [
    'Hello',
    { y: 'World' }
  ]
};

let { p, p: [x, { y }] } = obj;//这里p也作为了变量赋值
x // "Hello"
y // "World"
p // ["Hello", {y: "World"}]
let node = {
    type: "Identifier",
    name: "foo",
    loc: {
        start: {
            line: 1,
            column: 1
        },
    end: {
        line: 1,
        column: 4
    }
}
};
let { loc: { start }} = node;
console.log(start.line); // 1
console.log(start.column); // 1

混合解构

可以混合使用对象解构和数组解构来创建更多复杂的表达式

let node = {
    type: "Identifier",
    name: "foo",
    loc: {
        start: {
            line: 1,
            column: 1
        },
        end: {
            line: 1,
            column: 4
        }
    },
    range: [0, 3]
};
let {
    loc: { start },
    range: [ startIndex ]
} = node;
console.log(start.line); // 1
console.log(start.column); // 1
console.log(startIndex); // 0

解构模式中的loc和range仅代表它们在node对象中的属性

字符串解构

字符串也可以解构赋值(字符串被转换成了一个类似数组的对象)

const [a, b, c, d, e] = 'hello';
console.log(a);//"h"
console.log(b);//"e"
console.log(c);//"l"
console.log(d);//"l"
console.log(e);//"o"

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

const {length} = 'hello';
console.log(length);//5

变量的解构赋值作用

(1)交换变量的值

(2)从函数返回多个值(函数只能返回一个值,如果要返回多个值,只能将它们放在数组或对象里返回。解构赋值的出现,取出这些值就方便很多)

(3)函数参数的定义(解构赋值可以方便地将一组参数与变量名对应起来)

(4)函数参数的默认值

(5)提取JSON数据

(6)遍历Map结构(Map 结构原生支持 Iterator 接口,配合变量的解构赋值,获取键名和键值非常方便)

(7)输入模块的指定方法(加载模块时,往往需要指定输入哪些方法。解构赋值使得输入语句非常清晰)

参考:https://www.cnblogs.com/xiaohuochai/p/7243166.html(小火柴的蓝色理想)

原文地址:https://www.cnblogs.com/theblogs/p/10502299.html