es6语法之解构赋值

解构赋值也算是es6的一个特色操作,通过特定模式,从数组或对象中提取值,并对变量赋值,这种模式便被称为解构赋值。

1.数组的解构赋值

        let [a, b, c] = [6, 8, 9];
        console.log(a, b, c) //6 8 9

上面也有说到,这其实是一种“模式匹配”,所以下面一些场景也是支持解构的。

嵌套数组解构赋值

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

数组中部分元素进行解构赋值

        let [a, , c] = [1, 3, 4]
        console.log(a, c) //1 4

使用扩展运算符(...)进行解构赋值 

        let [a, ...b] = [1, 2, 3, 4, 5, 6]
        console.log(a,b) //1 [2, 3, 4, 5, 6]

当解构赋值时等号右边数组元素不足

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

不完全解构:当解构赋值只匹配部分等号右边的元素时,依旧能够解构赋值成功

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

通过上面的例子不难看出,解构赋值的要求还是比较宽松的,
但如果等号右边不是一个可遍历的结构,将会报错。
事实上,只要某种数据结构具有 Iterator 接口,都可以采用数组形式的解构赋值。(解构赋值会不会报错还得看是否是具有 Iterator 接口的数据结构)

默认值:解构赋值是可以设置默认值的,当等号右边数组元素===undefined时,默认值才生效。

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

'undefined'和null显然不能===undefined,所以默认值不生效

        let [a = 3, b = 6, ...c] = ['undefined', null];
        console.log(a, b, c) //undefined null []

如果默认值是一个表达式,那么这个表达式只有当用到时才会去求值。

        let [a = f()] = [];
        console.log(a)//6
        function f() {
            console.log('使用了默认值') //使用了默认值
            return 6;
        }

默认值也可以引用其他变量,前提是只能引用已经声明的变量。

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

        let [a = b, b = 1] = []
        console.log(a, b) //Uncaught ReferenceError: Cannot access 'b' before initialization

2.对象的解构赋值
对象的解构赋值与数组类似,但不同的是,对象解构赋值时变量名必须与属性名相同,才能取到正确的值,
否则会解构失败,解构失败变量值则等于undefined。

        let {a,b}={a:'555',c:'888'}
        console.log(a,b) //555 undefined

如果变量名和对象属性名实在不一致,但需要使用解构赋值,我们可以这样做

        let {a:b}={a:'666'}
        console.log(b) //666

所以对象解构赋值的本质其实是像下面这样的,但是其中a:a与b:b这种属性名和变量名相同的解构模式可以简写成a,b了,
如果等号右边没有属性e,导致取不到值,所以e的取值是undefined。

        let {a:a,b:b,c:d,e:e}={b:'777',a:'666',c:'999'}
        console.log(a,b,d,e) //666 777 999 undefined

跟数组一样,对象解构也支持嵌套结构的对象,下面的例子中,第一个a是变量,解构出来的就是属性a所对应的数组
而第二个a是解构模式,并不会被赋值。

        let obj = {
            a: [
                '111',
                {
                    y: '222'
                }
            ]
        };

        let {a,a: [x, {y}]} = obj;
        console.log(a,x,y) //(2) ['111', {y: '222'}] '111' '222'

嵌套对象解构的第二个例子

        const node = {
            a: {
                b: {
                    c: 1,
                    d: 2
                }
            }
        };

        let {a,a:{b,b:{c,d} } } = node;
        console.log(a,b,c,d) //{b:{c: 1, d: 2} } {c: 1, d: 2}  1  2

如果解构模式是嵌套的对象,而且子对象所在的父属性不存在,那么将会报错。
下面例子中对象{b}所在的父属性a不存在,则这段解构代码报错

let {a: {b} } = {b:'111', c: '222'}; // Cannot read properties of undefined (reading 'b')

对象的解构赋值可以取到继承的属性。

        const a = {};
        const b = {
            c: '111'
        };
        Object.setPrototypeOf(a, b);
        const {c} = a;
        console.log(c) // "111"

对象解构默认值

        var {a = 3,b:c=4,d:e=6,f} = {f:2,b:9};
        console.log(a,c,e,f)//3 9 6 2

由于数组本质是特殊的对象,因此可以对数组进行对象属性的解构。

        let arr = [1, 2, 3];
        let {
            0: a,
            1: b
        } = arr;
        console.log(a,b) //1,2

3.字符串解构赋值
字符串被解构赋值时,字符串被转换成了一个类似数组的对象,同时还能对这个length这个属性解构赋值。

        const [a, b, c, d, e] = 'jxy666';
        console.log(a, b, c, d, e) //j x y 6 6
        let {length : len} = 'jxy666';
        console.log(len) //6

4.数值和布尔值解构
解构赋值的规则是,只要等号右边的值不是对象或数组,就先将其转为对象

        let {toString: a} = 123;
        console.log(a === Number.prototype.toString)  // true
        let {toString: b} = true;
        console.log(a === Boolean.prototype.toString)  // true

由于undefined和null无法转为对象,所以对它们进行解构赋值,都会报错

        let { prop: x } = undefined; // TypeError
        let { prop: y } = null; // TypeError

5.函数参数的解构赋值

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

函数参数解构赋值默认值

        function move({a = 0,b = 1} = {a:2,b:3}) {
           console.log(a, b);
        }
        move({a: 3,b: 4}); // 3 4
        move({a: 3}); //3 1
        move({b: 4}); //0 4
        move({}); // 0 1
        move(); // 2 3

ES6 的规则是,只要有可能导致解构的歧义,就不得使用圆括号。
因此,建议只要有可能,就不要在模式中放置圆括号。
6.解构赋值的使用场景
交换变量的赋值

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

解构函数的返回值为数组        

        function jxy() {
            return [6,7,8]
        };
        let [a,b,c]=jxy();
        console.log(a,b,c);  //6 7 8

解构函数的返回值为对象

        function jxy() {
            return {a:'jxy',b:'666'}
        };
        let {a,b}=jxy();
        console.log(a+b); //jxy666

函数参数中应用解构赋值

        // 参数是一组数组形式的值
        function f([a, b, c]) {
            console.log(a, b, c)
        }
        f([1, 2, 3]);
        // 参数是一组对象形式的值
        function f({a, b, c}) {
            console.log(a, b, c)
        }
        f({a:'1', b:'5', c:'7'});

从json数据中提取某些属性值

        let jxyData = {
            a: 'jxy',
            b: "18岁",
            c: "开朗的"
        };
        let {a,c,b}=jxyData;
        console.log(c, a, b);//开朗的 jxy 18岁

函数参数的默认值解构,指定函数参数的默认值,避免在函数体内再进行判断

        function move({a = 0,b = 1} = {a:2,b:3}) {
           console.log(a, b);
        }
        move({a: 3,b: 4}); // 3 4
        move({a: 3}); //3 1
        move({b: 4}); //0 4
        move({}); // 0 1
        move(); // 2 3

map数据结构在进行遍历取值时,可以将每次遍历的值解构赋值

        const map = new Map();
        map.set('我是', 'jxy');
        map.set('jxy', '666');
        for (let [key, value] of map) {
            console.log(key + value);
        }
        // 我是jxy
        // jxy666

引入模块时,可以指定引入模块中某些方法

        const { SourceMapConsumer, SourceNode } = require("source-map");

你可能感兴趣的:(es6,学习方法,javascript,前端)