es6中的解构赋值、扩展运算符和rest参数使用详解


Posted in Javascript onSeptember 28, 2017

前言

本文主要给大家介绍了关于es6中解构赋值、扩展运算符和rest参数使用的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧。

es6中较为常用的书写风格

为了书写的方便,es6中提出了很多比较友好的书写方式,其中最为常见的属于以下几个:

  • 字符串模板 `abcdef${test}`
  • 解构赋值 let [a, b, c] = [1, 2, 3]
  • 扩展运算符 rest参数 ...

本文希望能够学习其中的主要的用法,方便书写和简洁性。

字符串模板

在以前的日子,我们经常捡到各种类别的字符串拼接,无论是跳转链接还是请求,很多时候见到这样的代码

let url = location.protocol + '//baidu.com/query?q=' + word +
   '&qn=' + queryWord;

现在书写的时候不需要这么多的+加好来连接,可以使用字符串模板变成这个样子

let url = `${location.protocol}//baidu.com/query?q=${word}&qn=${queryWord}`;

写起来还是简便不少,有一个简单的猜想,这个字符串模板会不会具有react、vue那样的效果,动态的绑定数据,也就是说字符串模板的内容会跟着模板中的变量变化而变化

let m = 'test';
let n = `m+:${m}`;
n //"m+:test"
m //"test"
m += 'noTest' //改变字符串模板中的 m 的值
m //"testnoTest"
n //"m+:test"

所以上面说的假想不会发生,react、vue都是存在虚拟dom来diff数据的不同,来出发数据的重新加载,以达到动态绑定的目的。

字符串模板的一些特性和注意

1、在模板字符串中如果需要使用 ` 字符的话,需要使用反斜杠转译 \`;

2、字符串模板可以表示多行字符串,所有的空格和缩进都会被保留在输出之中;

let k = `one line
 two line
 3 line`;
k //输出如下
"one line
two line
3 line"

3、字符串模板的 ${} 里面可以书写JavaScript的表达式,

四则运算

test:${1+1} //"test2"

函数

`TEST:${new Date()}` //"TEST:Wed Sep 27 2017 15:48:53 GMT+0800 (CST)"

如果大括号中的值不是字符串,将按照一般的规则转为字符串。比如,大括号中是一个对象,将默认调用对象的toString方法

var tt = {a:1,b:2};
`test:${tt}` //"test:[object Object]"
tt.toString() //"[object Object]"

如果模板字符串中的变量没有声明,将报错。

模板字符串甚至还能嵌套

解构赋值

ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring)。解构运算可以算是一种很优雅的书写方式,只要赋值表达式=的两边的模式相同的时候,左边的变量就会被赋予右边数组或者对象对应的值,直接看代码:

// 完全匹配模式
let [g, h, l] = ['gg', 'hh', 'll'];
g //"gg"
h //"hh"
l //"ll"

//部分匹配、设置初始值 【初始值需要对象或者数组的成员值严格等于undefined才会生效】
let [v, , x, z='zzz'] = ['vv', 'bb', 'xxxx'];
v //"vv"
x //"xxxx"
z // "zzz"

//对象解构 【注意对象解构时冒号 : 前面的是模式,用来和对象的键名匹配,不是变量】
let {a:aaa,b,c=9,d:ddd=9,e:eee=9,f} = {a:1,b:2,c:3,d:4}
aaa // 1
b //2
c //3
ddd //4
eee //9
f // undefined
//字面量的对象解构需要加上括号
({a, b} = {a:1, b:2})
({a, b, ...rest} = {a:1, b:2, c:3, d:4});

除了数组、对象之外,其实字符串、数字、布尔值都可以解构,不过并不是很实用,所以不过多的说明。

需要注意:解构不成功的,数组可能是长度不够完全匹配,对象可能是没有匹配的键名,那么返回的值都是undefined,而且一旦左侧匹配的格式出错和右侧的数据类型不对应的话(右侧是数组或者对象之外的类型)还会报错

使用场景

很多时候使用解构会带来很大的便利:

交换变量

let a =1, b=2;
[a, b] = [b, a];

获取接口或者函数返回的数组或者对象的某些部分

function f() {
 return [1, 2, 3];
}

let [a, , b] = f();

还可以配合正则表达式获取不同的部分内容

//就拿navigator.userAgent来说,想要获取不同的内容,类似如下:
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36"

let ua = /(Mac\s?OS\s?X\s?)([\d_]+).*Chrome\/([\d.]+)/.exec(navigator.userAgent);
/* ua = ["Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100",
  "Mac OS X ",
  "10_12_6",
  "61.0.3163.100"]

*/
let [ , ,macVersion, chromeVersion] = ua; //分别获取mac的系统版本和chrome的版本

扩展运算符 ...

扩展语法允许一个表达式在期望多个参数(用于函数调用)或多个元素(用于数组字面量)或多个变量(用于解构赋值)的位置扩展

字面量的扩展,

//数组字面量扩展
let test = [3,4,5],
 copyTest = [...test], // copyTest [3,4,5]
 extTest = [1,2,...test]; //extTest [1,2,3,4,5]
//对象字面量扩展
let obj = {a: 1, b: 2},
 copyObj = {...obj}, //
 extObj = {...obj, c: 3};

函数调用 作为实参

function myFunction(x, y, z) {
 return x+y+z;
 }
var args = [0, 1, 2];
myFunction(...args); //3

替代apply方法的参数使用数组的形式

Array.prototype.push.apply(arr) //=>// Array.prototype.push(...arr)

合并数组、对象

let array1 = [1,2,3], array2 = [4,5,6],array3 = [...array1, ...array2];

rest剩余参数(rest parameter)

剩余参数(rest parameter)语法允许我们将一个不定数量的参数表示为一个数组,

function sortRestArgs(...theArgs) {
 var sortedArgs = theArgs.sort();
 return sortedArgs;
}
 
alert(sortRestArgs(5,3,7,1)); // 弹出 1,3,5,7

听起来感觉和arguments他有点相似:

  • 剩余参数只包含那些没有对应形参的实参,而 arguments 对象包含了传给函数的所有实参。
  • arguments 对象不是一个真实的数组,而剩余参数是真实的 Array实例,也就是说你能够在它上面直接使用所有的数组方法,比如 sort,map,forEach,pop。
  • arguments 对象对象还有一些附加的属性 (比如callee属性)。

还可以和结构赋值一起使用

var [a, ...rest] = [1, 2, 3, 4];
console.log(a);//1
console.log(rest);//[2, 3, 4]

扩展运算和rest参数注意

对于三个点号...,三点放在形参或者等号左边为rest运算符; 放在实参或者等号右边为spread运算符,或者说,放在被赋值一方为rest运算符,放在赋值一方为扩展运算符。

注意

  • 在等号赋值或for循环中,如果需要从数组或对象中取值,尽量使用解构。
  • 在自己定义函数的时候,如果调用者传来的是数组或对象,形参尽量使用解构方式,优先使用对象解构,其次是数组解构。代码可读性会很好。
  • 在调用第三方函数的时候,如果该函数接受多个参数,并且你要传入的实参为数组,则使用扩展运算符。可以避免使用下标形式传入参数。也可以避免很多人习惯的使用apply方法传入数组。
  • rest运算符使用场景应该稍少一些,主要是处理不定数量参数,可以避免arguments对象的使用。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

Javascript 相关文章推荐
犀利的js 函数集合
Jun 11 Javascript
jQuery ctrl+Enter shift+Enter实现代码
Feb 07 Javascript
菜鸟javascript基础整理1
Dec 06 Javascript
Jquery实现的一种常用高亮效果示例代码
Jan 28 Javascript
JavaScript+html5 canvas绘制的圆弧荡秋千效果完整实例
Jan 26 Javascript
JavaScript 经典实例日常收集整理(常用经典)
Mar 30 Javascript
canvas绘制多边形
Feb 24 Javascript
JavaScript中闭包的详解
Apr 01 Javascript
深入理解Vue Computed计算属性原理
May 29 Javascript
微信小程序下拉刷新PullDownRefresh的使用方法
Nov 29 Javascript
Vue 实现显示/隐藏层的思路(加全局点击事件)
Dec 31 Javascript
针对Vue路由history模式下Nginx后台配置操作
Oct 22 Javascript
JS获取日期的方法实例【昨天,今天,明天,前n天,后n天的日期】
Sep 28 #Javascript
jquery实现左右轮播图效果
Sep 28 #jQuery
bootstrap table实现点击翻页功能 可记录上下页选中的行
Sep 28 #Javascript
JavaScript判断输入是否为数字类型的方法总结
Sep 28 #Javascript
详解Node全局变量global模块
Sep 28 #Javascript
React Native预设占位placeholder的使用
Sep 28 #Javascript
import与export在node.js中的使用详解
Sep 28 #Javascript
You might like
用PHP制作的意见反馈表源码
2007/03/11 PHP
dedecms模版制作使用方法
2007/04/03 PHP
php通过smtp邮件验证登陆的方法
2016/05/11 PHP
PHP互换两个变量值的方法(不用第三变量)
2016/11/14 PHP
PHP实现根据数组某个键值大小进行排序的方法
2018/03/13 PHP
如何实现浏览器上的右键菜单
2006/07/10 Javascript
javascript两段代码,两个小技巧
2010/02/04 Javascript
避免 showModalDialog 弹出新窗体的原因分析
2010/05/31 Javascript
js渐变显示渐变消失示例代码
2013/08/01 Javascript
Extjs改变树节点的勾选状态点击按钮将复选框去掉
2013/11/14 Javascript
js加减乘除丢失精度问题解决方法
2014/05/16 Javascript
JavaScript判断FileUpload控件上传文件类型
2015/09/28 Javascript
整理Javascript事件响应学习笔记
2015/12/02 Javascript
Js获取当前日期时间及格式化代码
2016/09/17 Javascript
vue组件父与子通信详解(一)
2017/11/07 Javascript
基于vue开发的在线付费课程应用过程
2018/01/25 Javascript
JS获取浏览器地址栏的多个参数值的任意值实例代码
2018/07/24 Javascript
解决vue接口数据赋值给data没有反应的问题
2018/08/27 Javascript
解决layui的table插件无法多层级获取json数据的问题
2019/09/19 Javascript
解决vue-router 二级导航默认选中某一选项的问题
2019/11/01 Javascript
react的hooks的用法详解
2020/10/12 Javascript
springboot+vue实现文件上传下载
2020/11/17 Vue.js
简单介绍利用TK在Python下进行GUI编程的教程
2015/04/13 Python
Python Excel处理库openpyxl使用详解
2019/05/09 Python
基于python 将列表作为参数传入函数时的测试与理解
2020/06/05 Python
python xlsxwriter模块的使用
2020/12/24 Python
有机童装:Toby Tiger
2018/05/23 全球购物
如何估计一张表的大小(假设该表中有1万条数据)
2016/03/27 面试题
初级Java程序员面试题
2016/03/03 面试题
护理专业本科生自荐信
2013/10/01 职场文书
优秀学生干部个人的自我评价
2013/10/04 职场文书
出生医学证明样本
2014/01/17 职场文书
地方白酒代理协议书
2014/10/25 职场文书
公务员检讨书
2014/11/01 职场文书
华清池导游词
2015/02/02 职场文书
发言稿之优秀教师篇
2019/09/26 职场文书