×
广告

Es6中变量的解构与赋值

96
随笔川迹
2017.05.29 17:47* 字数 3681
收听音频,戳如下链接.jpg

收听音频,戳链接,因旧号itclan已暂停使用,可移步新itclanCoder微信公众号,收听更多内容

前言

前端技术日新月异,现在出去面试,也基本都会问你Es6的一些内容了,越来越多的项目已经在用了的,这已是必然的趋势,无论是抱守Es5,还是现学Es6,Es7,时间也都会推着我们前进,今天一起来学习一下变量的解构赋值,本篇并不涉及什么高大上的内容,针对初学者,毫无压力,但需要对ES5的定义变量var关键字,数组,对象有所熟悉,对Es6新增的let,const有所了解,下面就我的学习和使用,跟大家分享一下使用心得,感受Es6不一样的魔力与强悍

什么是数组

如下代码示例所示

   var arr = [1,true,"itclan",null,undefined,function(){}],
        a = arr[0],
        b = arr[1],
        c = arr[2],
        d = arr[3],
        e = arr[4],
        f = arr[5]
  console.log(arr);//[1,true,"itclan",null,undefined, function]
  console.log(a,b,c,d,e,f); //1 true "itclan" null undefined (){}

官方解释:一组有序列值的集合
直白解释:按照次序排列的一组值,每一组中的值又叫做元素,元素与元素之间用逗号隔开,每个值在这个集合中都有一个位置,也就是对应的编号,以数字表示,从0开始,通常称为索引
特点:

  • 除了boolean,null,undefined,函数之外,遇到字符串时,需要用单引号和双引号给包裹起来,注意number不用
  • 无类型的,数组元素可以是任意类型,可以是number,boolean,null,undeinfed,对象,数组,函数等可构成一复杂的数据结构

什么是解构

官方定义:按照一定的模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(是针对数组或者对象中的值的提取和解析,在原有的结构基础上按照一定的规则进行重新定义结构,使变量赋值更为直观简单)
直白解释:模式匹配,映射关系,只要等号两边的模式相同,一一对应,左边的变量就会被赋予对应的值

数组的结构赋值.png

let与const命令同样适用解构赋值

03let与const同样适合变量的解构赋值.png
  • 可以适用嵌套数组进行解构
  • 拓展运算符...
    拓展运算符.png

注意:

  1. 可以对一个数组进行拆分
  2. 它是基于那些有遍历接口的
  3. 拓展运算符:是三个点,它好比rest参数的逆运算,将一个数组转换为用逗号分割的参数序列,该运算符主要用于函数调用
  • 解析不成功,变量的值就等于undefined(等式左边变量与等式右边变量值不对等的话,不对等的变量会变为undefined,相当于只声明变量,并没有赋值),若右边值多于左边变量数,多于的会被舍弃掉,但是有一种情况是不完全解构,即等号左边的模式只匹配等号右边变量值的一部分,这种情况解构依然是可以成功的,这种情况为不完全解构
    解构不成功,变量的值等于undefined

    关于其他出现undefined情况,你可以戳前文:精要javascript中的函数

等号右边不是数组(不是可遍历的结构),或是不具备可枚举(Interator)的接口,要么本身就具备Iterator接口

不具备inerator接口的会解构不成功

上面的表达式都会报错,左右等式两边若类型不对等的话,都会报错

允许指定默认值

允许指定默认值

对象的解构赋值

  • 对象的解构赋值
  • 解构不仅适用于数组,还可以用于对象
  • 注意:对象的解构与数组有一个重要的不同,数组的元素是按照次序排列的,变量的取值由它的位置决定,而对象的属性没有次序,变量必须与属性同名,才能取到正确的值
  • 等号左边的变量与等号右边的两个同名属性不一致,但是对取值完全没有影响
  • 变量没有对应的同名属性,导致取不到值,最后等于undefined
  • 对象的解构赋值的内部机制,是先找到同名属性,然后在赋给对应的变量,真正被赋值的是后者,而不是前者


    对象的解构赋值

对象的解构与数组一样,同样可以嵌套

  1. 注意如下示例line是变量,loc和start都是模式,不会被赋值
  2. 对象的解构可以指定默认值
  3. 默认值生效的条件是:对象的属性值严格等于undefined,导致默认值不会生效,如果解构失败,变量的值等于undefined


    对象的解构与数组一样,同样可以嵌套

字符串的解构赋值

字符串的解构赋值

注意

  • let,const对同一个变量不能重新声明,且必须先声明赋值,才能使用,否则会报错
  • 数字,对象无长度,但是函数有长度,且当无形式参数时,长度为0,它的长度由形式参数的个数而定,对于不可枚举循环遍历的对象,操作对象下面的方法时,无法用for循环,可以用for-in来操作对象循环遍历属性

数值和布尔值的解构赋值

解构赋值时,如果等号右边是数值或布尔值,则会转换为对象

  • 数值和布尔值的包装对象都具有toString属性,因此变量str,boo都能取到值
  • 解构赋值的规则是:只要等号右边的值不是对象,就先转换为对象
  • 注意:undefined,null无法转换为对象,所以对他们进行解构赋值都会报错


    数值和布尔值的解构赋值

函数参数的解构赋值

函数的参数解构赋值

上面的两段代码分别是没有使用解构赋值,和使用了解构赋值,前一个呢,是通过函数直接传参的形式,后一个呢,你可以理解为将圆括号内作为整个参数,传进去,函数multiply2的实际参数并不是一个数组,而是通过解构得到的变量x,y
两者性能比较:执行代码所消耗的时间,从结果得出,前者要优于后者,后者只是一种代码书写的简化,后者消耗的时间长一点,小段代码性能差别并不是很大,不受影响,但是若是很多的话,也是影响性能的,因为它先要解构,在赋值嘛,语法糖虽新,简化了操作,必然牺牲性能,有得必有失,适用就好


函数的参数解构与不解构性能比较

函数的参数的解构也允许适用默认值

函数result的参数是一个对象,通过这个对象进行解构,得到x和y的值,如果解构失败,则x和y等于默认值

函数的参数的解构也允许适用默认值

注意下面的一种写法与上面的区别,上面的是直接赋值,实际参数少于形式参数时,则会返回undefined,函数result的参数指定默认值,而不是为变量x和y指定默认值
函数Result的参数指定默认值,而不是为变量x和y指定默认值

解构赋值的用途

  • 用途一:变换变量的值:

  • 方法一:使用临时变量变换,第三个变量,两瓶水互换的实例


    临时变量变换
  • 方法二:不使用临时变量的方式:让其中一个变量变成一个a和b都有关系的值,这样可以先改变另一个变量的值,最后改变原修改的变量值


    不使用临时变量方式,让其中一个变量变成一个a和b都有关系的值
  • 方法三:变换变量值的方式,把变量对象变成了一个对象,这个对象保存着交换的键值对,最后赋值就可以了的


    变换变量值的方式
  • 方法四:使用数组,与上面的对象变换差不多


    使用数组
  • 方法五:数组替换,简单粗暴,一行代码交换了a和b的变量值


    数组替换
  • 方法六:使用Es6解构赋值的方法,允许我们提取数组和对象的值,对变量进行赋值


    使用Es6解构赋值
  • 用途二:从函数返回多个值
    定义一个函数,必须要有返回值,若没有,它会默认的返回一个Undefined值,
    如果要返回多个值,只能将其他放在数组或对象中返回,有了解解构赋值,取出这些值就很方便

    • 返回一个数组


      返回一个数组
    • 返回一个对象


      返回一个对象

函数参数的定义

如下代码实例所示:解构赋值可以方便的将一组参数与变量名对应起来
三个点表示的是,拓展运算符,基于那些有遍历接口的,可以对一个数组进行拆分,它好比rest参数的逆运算,将一个数组转为用逗号分割的参数序列,主要运用于函数调用,函数orderValue是一有序列值,而DisorderedValue函数后面的参数是一组无序列值
当参数是一组无序的值,通过这种写法,很方便的提取json对象中想要的参数,这里提取的是a,b,c要注意一点,若实参数多于形参数,上面形参数没有的话,它是会报错的


函数参数的定义
  • 提取JSON数据
    • 解构赋值对提取JSON对象中的数据是非常有用的


      提取JSON数据

函数参数的默认值

函数参数的默认值

通过原始的判断值的方式与Es6中的解构赋值的方式,对比可知,明显Es6的写法要简易得多

循环遍历Map结构与Set结构

  • 使用for循环,for-in,forEach,Object.keys(),for-of的比较
    • for循环:针对数组循环遍历属性是没有问题的,但是若是一json对象,就显示undefined了,json是没有长度的


      使用for循环,for-in,forEach,Object.keys(),for-of比较

      Map数据结构类似于对象,也就是键值对的集合,但是键的范围不限于字符串,各种类型的值(包括对象)都可以当做键,也就是说,Map结构提供了值对值的对应,键名与键值有对应的映射关系
      如下为Map构造器函数与for..of结合的使用,遍历属性,键名,键值


      Map结构结合for-of使用遍历属性

注意最后一个Set结构的使用,里面的代码中已经设置了Set参数,会提示Uncaught SyntaxError: Identifier 'iterable' has already been declared这么一个错误,并不是说明这段代码有任何问题,是由于这个Set结构之前已经声明一次了,你可以单独把这段代码复制粘贴,打开另外一个窗口控制台或者新建单独一个js脚本,进行测试即可,由此也可以得出Set()结构并不能重复声明,且该构造器函数的成员是唯一的,没有重复的值,因此可以用来作为数组的去重一个好的方法,想想之前原始的去重方法,什么数组下标比较,循环遍历元素比较,总之实现起来没有这么简单粗暴,这在面试笔试的时候,有时,短时间要想写出来,还真是费不少时间的(笔试过的深有感触)

小结:for循环,forEach(),for-in,Object.keys(),for-of遍历属性

共同点:可循环遍历属性

不同点:for循环遍历寻找,只针对数组等有length长度的,对于json对象无能为力,forEach循环遍历,是Es5中内置的方法,但是不能中断循环,使用break语句和return语句,for-in循环,遍历对象的属性,他不仅会遍历自定义属性还会遍历出原型下的属性,不推荐使用for-in来循环一个数组,因为,它不像对象,数组跟普通对象的属性不一样,是有序列值为指标的,for-in是用来循环带有字符串key的对象的方法,找到对象里面的属性名和属性值,当操作的是一个数组时,则用Object.keys(),而不需要时则选用for-in,因为for-in不仅遍历自定义属性,还会遍历出原型,继承的属性,如果不是自己想要的结果,我们必须通过简单的if语句进行过滤删选,以确保我们访问的是自定义属性,for-of是Es6新增的,最为强大,不仅弥补了forEach和for-in循环的短板,与for-in语法结构上相似,但它的功能很丰富,可以循环很多东西,属于全能型的,可以循环一个数组,循环一个字符串,循环一个类型化数组,循环Map,循环一个Set,循环DOM,循环一个拥有enumerable属性对象,循环一个生成器(以后在讲)
至于更多相关Map和set两种新增的数据结构,以后在详聊的

总结
其实,整篇文章主要是围绕着变量的解构赋值进行说明,从什么是数组开始,到数组的解构,一些新增的语法糖确实精简了不少代码,对于习惯了Es5,我只用var,没有使用过Es6的童鞋来说,可能刚开始有些抗拒的,觉得怪里怪气的,是真的人云亦云中的语法清晰,可读性和表现力增强,有待在不断使用当中领悟,或许标准就是精简,写得更少,做得更多,谈到了let与const同样适用于解构赋值,函数参数等的解构赋值,最重要的是莫过于变量解构的用途,以及结尾循环遍历Map结构与Set结构,关于for循环,forEach(),Object.keys(),for-in,for-of的使用

以下是本篇提点概要

  • 什么是数组
  • 什么是解构,数组解构
  • let与const命令同样适用解构赋值,允许指定默认值,对象的解构赋值,对象的解构与数组一样,同样可以嵌套,
  • 字符串的解构赋值,数值和布尔值的解构赋值,函数参数的解构赋值,函数的参数的结构也允许适用默认值,函数的参数的结构也允许适用默认值
  • 解构赋值的用途,变换变量的值,从函数返回多个值,提取json数据
  • 函数参数的定义
  • 循环遍历Map结构与Set结构,for循环,forEach(),for-in,Object.keys(),for-of遍历属性的比较
更多内容尽在微信itclanCoder公众号.jpg
技术文章
Web note ad 1