es6 - spreed & rest 【... 扩展运算符】
扩展运算符:…运算符
好处:简化书写长度,提升开发效率。
具备两个功能:
1、展开功能
2、收集功能
所以…运算符又可以叫做展开收集运算符。
他的不同作用需要在不同场景中使用才会出现:
a、读 - 展开作用,输出、打印的情况。读完输出散列的值
读取arg2这个数组,并返回散列的项
var arg2 = [1,2,3,4,5]; console.log(...arg2);// 读,展开数组成散列的项
b、写 - 收集作用,写入、整合的情况。写完得到一个数组
把实参这些散列项写入到args里边并返回一个数组
function test(...args){ console.log(args);//写,把散列的项写入到一个数组中 } test(1,2,3,4,6);
不光这一种用法,他还可以有选择性的写:
如下图,把扩展运算符写到最后,前边有单独的行参:
* 但是尝试把…写在行参中间,就会报错:
展开作用【读】的应用:
用法一:把聚合的值展开成散列的值。
var arg2 = [1,2,3,4,5]; console.log(...arg2);// 读,展开数组成散列的项 // 比如写…[1,2,3] 相当于写 1,2,3
观察了一下babel编译后的代码,是让log调用时使用apply的原理调用:
往apply的第二个参数处传入一个数组,数组在apply内部就会被一一展开成一个参数列表,log接收到的就是这个展开的参数列表,
执行console.log再次打印就是这个参数列表被一一打印了。这么看来apply也有展开数组的作用。
用法二:数组合并
// 读操作 - 数组合并 let arr1 = [1,2,3,4], arr2 = [6,7,8,9], newArr = [...arr1,...arr2]; console.log(newArr); // 相当于下边的写法: let concatArr = [].concat(arr1,arr2); console.log(concatArr);
实际上babel编译后确实是这么处理的:
这也是他语法糖的说明。
这种方法如果用来做数组克隆的话,也是一种浅克隆。举例说明:
var arrA = [{
a: 1,
b: 1
},
'b',
{
a: 2,
b: 2
}
];
var arrB = [...arrA];
console.log(arrB) arrB[0].a = '浅克隆?';
arrB[1] = '浅克隆!';
console.log('arrA:', arrA, 'arrB', arrB);
打印结果:
收集作用【写】的应用:
比如我们写一个求和函数:
function getSum() {
let len = arguments.length,
sum = 0;
for (let i = 0; i < len; i++) {
sum += arguments[i]
}
return sum
}
console.log(getSum(1, 2, 3, 4, 6));
这样写的原理是利用arguments实质为一个伪数组,遍历这个伪数组,把每一项累加求和。
因为之所以叫伪数组,就是因为他们是假数组,不能随心所欲的用数组的方法(比如forEach遍历),必须通过转换。
【更多伪数组转换为数组的方法见这里】https://www.cnblogs.com/padding1015/p/10106957.html:
如果我们想用数组的方法,就得把arguments这个伪数组转化为数组再进行处理。
function getSum() {
let arr = Array.prototype.slice.call(arguments); // 转换伪数组为真数组。
return arr.reduce((pre, cur) => {
return pre += cur;
}, 0);
}
console.log(getSum(1, 2, 3, 4, 6));
奇迹就是,当我们利用扩展运算符的收集作用后,我们就可以直接使用扩展运算符收集后的结果,而这个结果就是一个数组格式:
function getSum(...arr) {
// let arr = Array.prototype.slice.call(arguments);为了和上边做清晰的对比,我直接注视了这一句而不是直接删掉了。
return arr.reduce((pre, cur) = >{
return pre += cur
},
0)
}
console.log(getSum(1, 2, 3, 4, 6));
在有扩展运算符的协助下,我们想在求和函数中新增点功能:先排序去掉最大值和最小值后求平均数
如此直接用数组的方法就更方便了:
比如我们可以先用Array的sort函数排序、再用pop、shift去掉前后两项,之后再用forEach或者reduce求和,最后用和/arr.length这个简单的思路实现。
实现起来一气呵成,毕竟扩展运算符收集的就是一个数组,不用原生方法就浪费了。
这样我不仅开始怀疑扩展运算符收集作用的原理就是一个函数接收多个实参后将arguments转换为了真数组。
我把以上代码使用babel进行转换,得到编译后代码如下图右侧代码:
虽然转换伪数组为真数组的做法和我们的常用写法不一样,但是es5转换后代码的根本就是将arguments伪数组转换为数组并使用。
倒是给我们提供了另一种转换伪数组的方法。
ES7里边的扩展运算符
es6的扩展运算符只能展开一个数组
在es7中可以展开一个对象,但必须是在对象里边使用扩展运算符展开对象,且不能让对象在数组中展开([…{}]这种展开需要iterator)。
扩展对象举例 - 类似下面这种写法:
得到的obj2如下:
可见,obj里边的键值对被克隆到了obj2当中。
这段代码被babel后的样子见下边:
和他的作用看上去一样,被babel编译后的代码就是一层拷贝。但是有点特殊的是,他是一种浅拷贝(其他深浅拷贝方法的合集见相关笔记章节):
为了证明他是浅拷贝,我把代码稍微修改,增加一个引用类型的属性值:
得到obj.IDCard.address和obj2修改后的一样,都是'Hang Zhou CHINA';
多提另一种克隆方法:
Object.assign()
语法:Object.assign(目标对象,克隆对象1,克隆对象2);
会以浅克隆的方式,将后边对象的值复制到目标对象里边去。
同样,再来对比一下:
es6用babel转成es5后的样子
展开作用被babel后的样子:
…展开作用用于合并数组时,babel编译后的代码:
扩展运算符的收集作用被编译后的代码:
es7中展开对象的功能,被编译后的代码:
2019-05-04 17:06:09
es6 - spreed & rest 【... 扩展运算符】的更多相关文章
- ES6学习笔记-扩展运算符(...)
扩展运算符的定义: es6中引入扩展运算符(...),它用于把一个数组转化为用逗号分隔的参数序列. 它常用在不定参数个数时的函数调用,数组合并等情形. 用法一:不定参数个数时的函数调用 <scr ...
- es6可变参数-扩展运算符
es5中参数不确定个数的情况下: //求参数和 function f(){ var a = Array.prototype.slice.call(arguments); var sum = 0; a. ...
- es6 学习小记 扩展运算符 三个点(...)
参考: es6 扩展运算符 三个点(...) 经常回顾,方能真正掌握. 一.含义 扩展运算符( spread )是三个点(...).它好比 rest 参数的逆运算,将一个数组转为用逗号分隔的参数序列. ...
- ES6数组的扩展运算符
一.基本使用 ES6中函数可以使用 rest参数 接收函数的多余参数,组成一个数组,放在形参的最后面. let fn = (a, ...value) => { console.log(a); c ...
- (...)ES6三点扩展运算符
扩展运算符将一个数组转为用逗号分隔的参数序列 console.log(...[a, b, c]) // a b c 用于: 1 将一个数组,变为参数序列 let add = (x, y) => ...
- Vue的三个点es6知识,扩展运算符
Vue中的三个点在不同情境下的意思 操作数组 //里面放自己定义的方法 methods: { /** * 把数组中的元素孤立起来 */ iClick() { let iArray = ['1', '2 ...
- ES6 rest与扩展运算符
1.rest 变量将多余的参数放入数组中. function add(...values) { let sum = 0; for (var val of values) { sum += val; } ...
- 关于ES6的对象扩展运算符
对象的扩展运算符(...),用于取出参数对象中的所有可遍历属性,然后拷贝到当前对象之中 对象扩展运算符: 1. 复制对象 let obj1 = { x: 1, y: 2, z: 3 } let obj ...
- call,apply,bind与es6的数组扩展运算符...
js中每一个Function对象都有一个apply个一个call方法: function.apply(thisObj,[argArray]); function.call(thisObj,arg1,a ...
- ES6 扩展运算符 三个点(...)
它是什么 es6中引入扩展运算符(...),它用于把一个数组转化为用逗号分隔的参数序列,它常用在不定参数个数时的函数调用,数组合并等情形.因为typeScript是es6的超集,所以typeScrip ...
随机推荐
- Base64和本地以及在线图片互转
package com.ruoyi.common.utils; import java.io.ByteArrayOutputStream; import java.io.FileInputStream ...
- nginx 查看 并发连接数
通过命令查看 #netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}' TIME_WAIT 17 ESTABLISHE ...
- java 动态代理 Proxy.newProxyInstance 使用心法
使用JDk的Proxy类的静态方法newProxyInstance ,让JVM自动生成一个新的类,类中包含了inerfaces参数中的所有方法,每个方法都调用h.invoke 方法 AOP ...
- 【翻译】Tusdotnet中文文档(3)自定义功能和相关技术
自定义功能和相关技术 本篇按照如下结构翻译 自定义功能 自定义数据仓库 相关技术 架构和总体概念 自定义数据仓库 tusdotnet附带一个存储库TusDiskStore,它将文件保存在磁盘上的一个目 ...
- join 和子查询优化
一次在家查看数据的时候,列表展示特别慢,就查看了一下,把sql语句拿出来运行居然要4,5秒,当时就感觉有问题,语句用的join链接2个表,感觉没啥错误,为啥会这么慢,然后改用了子查询链接,发现快了许多 ...
- 修改Nginx配置参数解决http状态码:413上传文件大小限制问题
修改Nginx上传文件大小限制 我们使用ngnix做web server的时候,nginx对上传文件的大小有限制,默认是1M. 当超过大小的时候会报413(too large)错误.这个时候我们要修改 ...
- Spring Boot 使用 JWT 进行身份和权限验证
上周写了一个 适合初学者入门 Spring Security With JWT 的 Demo,这篇文章主要是对代码中涉及到的比较重要的知识点的说明. 适合初学者入门 Spring Security W ...
- English--倒装句
English|倒装句 这一块主要进行英语中倒装句与强调句的透析,希望大家可以掌握倒装句.因为倒装句,实在是太常见了,加油哦~~ 前言 目前所有的文章思想格式都是:知识+情感. 知识:对于所有的知识点 ...
- 设计模式之(十三)外观模式(Facade)
外观模式思想 历史上牛人中成功逆袭,实现人生辉煌的人很多,这群人最耀眼的无疑是明太祖朱元璋,从一个放牛讨饭的最低层小屌丝逆袭到人类权力顶峰开国皇帝,确实是我等膜拜的对象.在发不断的发展过程中,其实就在 ...
- [转]localhost、127.0.0.1和0.0.0.0和本机IP的区别
一.IP地址是什么 首先,我们要知道网络中的相互访问其实就是在进行两者间的数据传递.就如同送快递一样,快递发出只有知道你的住址信息,才能将快递送到你的手中.而在网络访问时,只有知道你在网络中的地址信息 ...