前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >ES6语法学习(变量的解构赋值)

ES6语法学习(变量的解构赋值)

原创
作者头像
帅的一麻皮
修改2020-06-22 14:23:30
5040
修改2020-06-22 14:23:30
举报
文章被收录于专栏:前端与Java学习前端与Java学习

概念

ES6中允许按照一定的模式从数组和对象中提取值,然后对变量进行赋值,这就是解构。

01-数组的解构赋值

1.1-基本用法

在没有解构赋值前只能直接定值:

代码语言:javascript
复制
     let a = 1;
     let b = 2;
     let c = 3;

ES6中允许写成下面这样:

代码语言:javascript
复制
    let [a, b, c] = [1, 2, 3]
    console.log(a, b, c); //1,2,3

1.2-嵌套数组解构

例:

代码语言:javascript
复制
    let [foo, [[bar], baz]] = [10, [[20], 30]]
    console.log(foo, bar, baz); //10,20,30
    let [, , third] = ["foo", "bar", "baz"];
    console.log(third); //baz
    let [x, , y] = [1, 2, 3]
    console.log(x,y);//1 3
    let [head,...tail] = [1,2,3,4,5];
    console.log(head);//1
    console.log(tail);//[2, 3, 4, 5]
    let [x,y,...z] = "a";
    console.log(x,y,z);//a undefined []    

如果解构不成功,变量的值就等于undefined

例:

代码语言:javascript
复制
 let [foo] = [];
 let [bar,baz] = [1];
 console.log(foo,baz);//undefined undefined

另一种情况是不完全解构:就是等号左边的模式只匹配一部分等号右边的数组,这样解构依然可以成功

例:

代码语言:javascript
复制
 let [x,y] = [1,2,3];
 let [a,b,c] = [1,[2,3],4]

1.3-解构报错情况

如果等号的右边不是数组(或者说不是可遍历的解构),那么会报错

例:下面的语句都会报错,因为等号右边的值或是转为对象以后不具备Iterator接口,或者是本身就不具备Iterator接口

代码语言:javascript
复制
    let [foo] = 1;//TypeError: 1 is not iterable
    let [foo] = false;//TypeError: false is not iterable
    let [foo] = NaN;
    let [foo] = undefined;
    let [foo] = null;
    let [foo] = {}; 

1.4-Set结构数据也可以使用解构赋值

代码语言:javascript
复制
let [x,y,z] = new Set(['a','b','b','c']);
console.log(x,y,z);//a b c

1.5-解构赋值允许指定默认值

代码语言:javascript
复制
    let [foo = true] = [];
    console.log(foo);//true
    let [a,b="1"] = ["2"]
    console.log(a,b);//2 1
    let [x,y="b"] = ["a",undefined];
    console.log(x,y);//a b

注意:ES6 内部使用严格相等运算符(===)判断一个位置是否有值,所以如果一个数组成员不===undefined,默认值就不会生效

代码语言:javascript
复制
    let [x=1] = [undefined];
    console.log(x);//1
    let [y=2] = [null];
    console.log(y);//null 

如果默认值为一个表达式,那么这个表达式是惰性求值,只有在用到时才会求值

所以下面的代码中因为x能取到值,所以函数f根本不会执行

代码语言:javascript
复制
 function f() {
 console.log("aaa");
    }
 let [x = f()] = [1];
 console.log(x);//1

默认值也可以引用解构赋值的其他变量,但是变量必须已经声明。

代码语言:javascript
复制
    let [x = 1, y = x] = [];
    console.log(x, y); //1,1
    let [x = 1, y = x] = [2];
    console.log(x, y);//2,2
    let [x = y, y = 2] = [];//报错 因为x用到默认值y的时候,y还没有声明

02-对象的解构赋值

解构不仅可以用于数组,还可以用于对象。

  • 对象的解构和数组有一个重要的不同:
    •                 数组的元素是按次序排列的,变量的取值是由它的位置决定的
    •                 而对象的属性没有次序,变量必须与属性同名才能取到正确的值

注意:对象的解构赋值的内部机制是先找到同名属性,然后再赋值给对应的变量,真正被赋值的是后者,而不是前者

2.1-基本用法

例:

代码语言:javascript
复制
 let {foo,bar } = {foo:"aaa",bar:"bbb"};
 console.log(foo,bar);//aaa bbb
 let {bar,foo} = {foo:"aaa",bar:"bbb"};
 console.log(bar,foo);//bbb aaa
 let {baz} = {foo:"aaa",bar:"bbb"};
 console.log(baz);//undefined

2.2-变量名和属性名不同

例:

代码语言:javascript
复制
 var {foo:baz} = {foo:'aaa',bar:'bbb'};
 console.log(baz);//aaa
 console.log(foo);//错误 foo is not defined
 let obj = {
     first: 'hello',
     last: 'world'
 }
 let {first:f,last: l } = obj;
 console.log(f,l);//hello world

2.3-解构也可以用于嵌套解构的对象

代码语言:javascript
复制
 let obj = {
    p:[
         'Hello',
         {y:"world"}
      ]
 }
 let {p:[a,{y}]} = obj;
 console.log(a,y);//Hello world

上面的的p是模式,不是变量,因此不会被赋值,如果p也要作为变量赋值,则需要写成下面这样

代码语言:javascript
复制
 let {p,p:[a,{y}]} = obj;

再来看一个案例:下面的代码有三次解构赋值,分别是对locstartline三个属性的解构赋值。需要注意的是,最后一次对line属性的解构赋值之中,只有line是变量,locstart都是模式

代码语言:javascript
复制
var node = {
    loc:{
      start:{
          line:1,
          column:5
       }
     }
 }
 var {loc,loc:{start},loc:{start:{line}}}=node
 console.log(line);//1
 console.log(loc);//Object {start:Object}
 console.log(start);//Object {line: 1, column: 5}
 //数组的本质是特殊的对象,因此可以对数组进行对象属性的解构
 let arr =[1,2,3];
 let {0:first,[arr.length-1]:last} = arr;
 console.log(first,last);//1 3

03-字符串、数值、布尔值的解构赋值

字符串也可以解构赋值,这是因为字符串被转换成了一个类似数组的对象

代码语言:javascript
复制
 const [a,b,c,d] = "hello";
 console.log(a,b,c,d);//h e l l

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

代码语言:javascript
复制
 let {length:len} = "hello";
 console.log(len);//5

解构赋值的时候,如果等号右边的是数值和布尔值,则会先转为对象

数值和布尔值的包装对象都有toString属性,所以变量s都能取到值

代码语言:javascript
复制
 let {toString:s} = 123;
 console.log(s == Number.prototype.toString);//true
 let {toString:s} = true;
 console.log(s == Boolean.prototype.toString);//true

解构赋值的规则是,只要等号右边的值不是对象或者数组,就先将其转换成对象。

由于undefined和null无法转对象,所以对他们进行解构赋值的时候会报错

代码语言:javascript
复制
let {b} = undefined;//报错
let {c} = null;//报错

04-函数参数的解构赋值

4.1-函数的参数也可以解构赋值

代码语言:javascript
复制
function add([x, y]) {
        return x + y;
    }
console.log(add([2, 3])); //5

4.2-函数的参数的解构也可以使用默认值

代码语言:javascript
复制
    function move({x = 0,y = 0} = {}) {
        return [x, y];
    }
    console.log(move()); //[0, 0]
    console.log(move2({})); //[0,0]
    console.log(move({
        x: 1
    })); //[1, 0]
    console.log(move({
        x: 2,
        y: 4
    })); //[2, 4]

注意下面的写法会得到不一样的结果,下面的代码是给函数的参数设置默认值,而不是变量x和y

代码语言:javascript
复制
    function move2({x,y} = {x: 0,y: 0}) {
        return [x, y]
    }
    console.log(move2({x: 2,y: 4})); //[2, 4]
    console.log(move2({x: 2})); //[2, undefined]
    console.log(move2({})); //[undefined, undefined]
    console.log(move2()); //[0, 0]

04-解构赋值的应用

4.1-交换变量的值

代码语言:javascript
复制
        let x = 123;
        let y = 666;
        [x, y] = [y, x];
        console.log(x, y); //666 123

4.2-从函数返回多个值

代码语言:javascript
复制
        //返回一个数组
        function exam1() {
            return [1, 2, 3];
        }
        let [a, b, c] = exam1();
        console.log(a, b, c); //1 2 3

        //返回一个对象
        function exam2() {
            return {
                name: "张三",
                age: 18
            }
        }
        let {name,age} = exam2();
        console.log(name, age); //张三 18

4.3-函数参数的定义:解构赋值可以方便的将一组参数与变量名对应起来

代码语言:javascript
复制
        //参数是一组有次序的值
        function fn1([x, y, z]) {
            //...
            console.log(x,y,z);
        }
        fn1([1,2,3]);
        //参数是一组无次序的值
        function fn2({x,y,z}) { 
            //...
            console.log(x,y,z);
        }
        fn2({z:20,y:19,x:18})

4.4-提取JSON数据

解构赋值对提取JSON对象中的数据尤其重要

代码语言:javascript
复制
        let jsonData = {
            id:42,
            status:"OK",
            data:[666,777],
        }
        let {id,status,data} = jsonData;
        console.log(id ,status,data);//42 "OK"  [666, 777]

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 概念
  • 01-数组的解构赋值
    • 1.1-基本用法
      • 1.2-嵌套数组解构
        • 1.3-解构报错情况
          • 1.4-Set结构数据也可以使用解构赋值
            • 1.5-解构赋值允许指定默认值
            • 02-对象的解构赋值
              • 2.1-基本用法
                • 2.2-变量名和属性名不同
                  • 2.3-解构也可以用于嵌套解构的对象
                  • 03-字符串、数值、布尔值的解构赋值
                  • 04-函数参数的解构赋值
                    • 4.1-函数的参数也可以解构赋值
                      • 4.2-函数的参数的解构也可以使用默认值
                      • 04-解构赋值的应用
                        • 4.1-交换变量的值
                          • 4.2-从函数返回多个值
                            • 4.3-函数参数的定义:解构赋值可以方便的将一组参数与变量名对应起来
                              • 4.4-提取JSON数据
                              领券
                              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档