ES6一路扩展,字符串、数组、数值、对象无一“幸免”,ES6说要雨露均沾,函数也不能落下,今天,就来讲解ES6对函数的扩展。

参数的默认值

在开发中,给函数的参数指定默认值,是很普遍很常见的一个需求,我们先来回顾一下传统的实现方式,对比着看更好理解:

  1. function person(n,a){
  2. var name = n || 'Zhangsan';
  3. var age = a || 25;
  4. }

上面是传统的实现方式,通过或运算实现,原理:如果运算符 || 左侧为true,直接返回左侧的值,否则返回右侧的值; 在person函数内,如果参数n没有传参,那么变量name得到的值就是“Zhangsan”,如果传参了,变量name的值就为参数n的值。

但是,前提是参数对应的布尔值不能false(比如:数字0,空字符串等转换成布尔值就是false),这就使得这种传统的实现方式存在一定的不足和缺陷。

这个时候ES6说:“竟然这种写法有缺陷,咱就不要用这种写法了,我给你们带来一种新的实现方式,比这种写法好用多了,更简捷”。

  1. function person(name = 'Zhangsan',age = 25){
  2. console.log(name,age);
  3. }
  4.  
  5. person();//结果:Zhangsan 25
  6. person('Lisi',18);//结果:Lisi 18

看,我们把默认值的设定放在了参数上:(name = 'Zhangsan',age = 25),这样就实现了参数name的默认值为‘Zhangsan’,age的默认值为25。而不需要在函数体内进行检测,函数体内可以专注对参数的使用或者运算,再也不用担心函数的实际传参情况了。

上面的案例,我们对person( )函数进行两次调用,区别是有传参数没传参数,运行的结果也符合我们的预期:没传参,得到的是默认值Zhangsan 25,传参就会得到传入的参数值:Lisi  18。

但是,多留个心眼,凡事总会有但是,如果函数有多个参数,但只有部分需要指定默认值,另一部分不需要的话,那么,**设定默认值的参数一定要放在最后。**看案例:

  1. //错误写法
  2. function person(age = 25,name){
  3. console.log(name,age);
  4. }
  5.  
  6. //正确写法
  7. function person(name,age = 25){
  8. console.log(name,age);
  9. }

上面的person函数,两个参数name和age,其中只有age需要指定默认值,name不需要,那么,age的排序就必须放在最后,name放在前面**。也就是有默认值的参数后面不能再跟不需默认值的参数了。**

另外,只有当传入的参数为undefined,才会触发默认值赋值。否则,哪怕你传的参数值为0,false,null都不会触发默认值赋值,这就完美的解决了传统实现方式的弊端,试试看:

  1. function person(age = 12){
  2. console.log(age);
  3. }
  4.  
  5. person();//结果:12
  6. person(undefined);//结果:12
  7.  
  8. person(0);//结果:0
  9. person(null);//结果:null

看person( )函数的4次调用和结果,只有不传或者传入undefined的时候才会触发默认值赋值,得到12,传入数字0或者null都不会触发默认值赋值。

还有一个要注意的地方,函数的参数是默认声明的,声明过的变量,就不能用let或者const关键字再次声明,否则会报错的,不信给你看一个案例:

  1. function person(age = 12){
  2. let age = 25;//错误,再次声明age
  3. }

上面这种情况,函数被调用后,就会报错,会提示你age已经被声明过了,你别再声明它了。

rest参数

rest参数,这是一个新的概念,rest的中文意思是:剩下的部分。

如果用在函数上,就代表是获取函数剩下部分的参数。具体是什么意思?我们还是得看案例才好理解,假设现在我们有这样的一个需求:将一组数字进行求和,然后把求和的结果赋值到一个变量去,我们用rest参数实现:

  1. //求和函数,得到的结果赋值到result
  2. function sum(result,...values){
  3. //打印values看看是什么
  4. console.log(values);
  5. //结果:[1,2,3,4]
  6.  
  7. //进行求和
  8. values.forEach(function (v,i) {
  9. //求和得到的结果存到result
  10. result += v;
  11. });
  12. //打印出求和的结果看看
  13. console.log(result);
  14. //结果:10
  15. }
  16.  
  17. //存储求和结果的变量res
  18. var res = 0;
  19. //调用sum函数
  20. sum(res,1,2,3,4);

上面的代码注释把每一步都写得很详细,首先,我们会看到一个陌生的语法:...values;咦?这是什么鬼?这是一种新的写法,也就是我们要介绍的rest参数,它代表的意思是:在实参中,除了第一个参数以外,剩余的参数都会被...values获取到。

在上面的案例中:sum(res,1,2,3,4),也就是除去实参 res 以外的参数,它们是1,2,3,4一共4个参数。它们全被...values收入囊中,接着,我们打印了values,看到的结果是一个数组:[1,2,3,4],也就是这4个参数被装在了一个数组中,我们想要使用这4个参数的话,就可以用数组的方法来对他们进行处理,所以我们用了forEach方法对它们进行了循环,并求和,把求和结果存储到了变量res中,最后我们打印出结果,得到了数字10,也就是数字1,2,3,4的求和结果。

(上面这段有点长,耐心读完了吗?读不懂,可以拉上去再阅读一遍上面的代码案例)

上面的案例主要是介绍了rest参数的用法,首先是表示法:...values(三个点+变量名);其次,values是一个数组;我们要学会这两点即可。

要注意的是,rest参数必须是函数的最后一个参数,后面不能再跟其他参数,什么意思呢?看案例:

  1. //错误写法
  2. function sum(result, ...values, mult){
  3. //rest参数...values后面还有一个参数mult
  4. }
  5. //正确的写法
  6. function sum(result, mult, ...values){
  7. //rest参数...values放在最后
  8. }

上面有错误和正确的两种表示,在注释上有说明原因。总之rest参数后面不能再跟有其他参数。

rest参数并不是适合所有的函数使用,只在特定的情境下会比较适用,比方说刚刚案例中的求和函数,就十分适合要rest参数把实际的参数收集起来放在数组中进行求和,在适当的情况下使用它可以事半功倍,减少代码量,提高开发效率。

扩展运算符

上面讲到的rest参数,它的表示法使用...(三个点),它除了用在rest参数中,还有其他用途,我们称这种表示法为扩展运算符,那么,它还有什么作用呢?

它一般结合数组使用,把数组的元素用逗号分隔开来,组成一个序列。我们看一下实际案例:

  1. function sum(a,b) {
  2. return a+b ;
  3. }
  4.  
  5. let arr = [2,3];
  6. //用扩展运算法将数组[2,3]转换成2,3
  7. sum(...arr);
  8. //结果:5

上面的sum( )函数是简单的将两个数字相加求和,参数是两个普通的参数x,y,并不是什么高逼格的rest参数,所以我们运用了扩展运算符...将数组[  2,3 ] 转成了 2,3 两个普通的数列,再传进sum( )方法,对应上x,y两个参数。实际上,sum( ...arr ) 的效果相当于sum( 2,3 ) 。

从这个案例我们就可以理解扩展运算符...的作用了,它可以将一个数组转成一个对应的参数数列。在实际开发中,你可以根据扩展运算符的作用,可以灵活运用,实现各种效果。

箭头函数

箭头函数,这又是一个新概念,ES6给我们介绍一种全新的定义函数的方式,就是用箭头符号(=>),故得名为箭头函数。具体怎么用,我们来看案例:

  1. //传统写法
  2. var sum = function(a) {
  3. return a ;
  4. };
  5.  
  6. //箭头函数写法
  7. var sum = a => a;

什么?第二种写法这么简短.....不敢信!!

上面演示了两种写法,函数的作用都是一样的,传入参数a,直接返回a;第一种传统的写法大家都熟悉,我们看看第二种写法:a=>a; 这里的第一个a代表是传进去的参数,箭头=>后面的a表示函数体;也许大家跟我一样,很不习惯,但这种写法确实简洁了很多。

看到这里,有开发经验的“老司机”可能会问:如果传入的参数不止一个,或者函数体不是简单的返回a,需要做一些其他的运算,含有多条语句的话,怎么办?

问得好,对于这种情况,我们又有另一种处理办法。举个例子,假如我们给函数传入2个参数,然后进行相加运算,我们用箭头函数来实现:

  1. //箭头函数写法
  2. var sum = (a,b) => {return a+b}
  3. sum(1,2);//结果:3

注意上面的参数和函数体部分,如果参数超过1个的话,需要用小括号()括起来,函数体语句超过1条的时候,需要用大括号{ }括起来。

箭头函数的最大作用就是简化函数的实现,大大地减少代码量。来举个例子对比一下,假设我们现在要对一个数组 [ 1,2,3,4 ] 里面的数求和,我们分别用传统的方式和箭头函数都实现一次,大家看看差别:

  1. //传统的写法
  2. var sum = 0;
  3. [1,2,3,4].forEach(function(v){
  4. sum += v;
  5. });
  6.  
  7. //箭头函数的写法
  8. var sum = 0;
  9. [1,2,3,4].forEach(v => sum+=v);

大家对比一下,用箭头函数代替了传统的匿名函数,确实减少了代码量。

今天讲解的函数扩展都是一些新概念,新语法。也许你看懂了,但是过段时间会忘记,不用慌,这很正常,只有通过多练习、多使用才会记住。如果你现在的项目还未使用到这些知识的话,不妨先收藏起来,有空的时候翻看一下,也是很有帮助的,因为ES6是趋势,总有一天会进入你的代码中

本节小结

总结:ES6为函数的扩展包括:参数的默认值、rest参数、扩展运算符(...)以及箭头函数。它们有一个共同的有点就是:使得代码更加简洁,结合需求灵活使用,可以大大地提高开发效率。
更多前端学习内容文章干货请关注我的专栏(不断更新)

阿里名厂标准web前端高级工程师教程目录大全,从基础到进阶,看完保证您的薪资上升一个台阶

在这里我给大家准备了很多的学习资料

其实你与阿里工程师的差距只差这些东西

ES6中对函数的扩展的更多相关文章

  1. ES6中的数组方法扩展

    上一篇文章小编简单介绍了在ES6中,一些常用的方法和一些简单的应用,在这篇文章中,小编将针对ES6中数组常用方法进行扩展,相信经过这篇文章之后,每一位小伙伴下班时间会有所提前,就算从原来的996变成9 ...

  2. Es6中箭头函数与普通函数的区别

    Es6中箭头函数与普通函数的区别? 普通function的声明在变量提升中是最高的,箭头函数没有函数提升 箭头函数没有属于自己的this,arguments 箭头函数不能作为构造函数,不能被new,没 ...

  3. ES6 入门系列 - 函数的扩展

    1函数参数的默认值 基本用法 在ES6之前,不能直接为函数的参数指定默认值,只能采用变通的方法. function log(x, y) { y = y || 'World'; console.log( ...

  4. ES6入门之函数的扩展

    函数js原有的: 属性:arguments[].caller(调用该函数的引用,注意与callee分别开,callee指的是调用函数本身经常在递归中出现).length(形参个数).prototype ...

  5. ES6中对数值的扩展

    上一节和大家学习了字符串的扩展,这一节轮到了数值,我们一起来学习数值的扩展. 剧透一下,这一节并不会很烧脑,都是介绍类的知识讲解,理解性的东西不多,初学者们也可以愉快地看完. 传统的写法 在介绍数值的 ...

  6. es6中的函数

    ES6 允许为函数的参数设置默认值,即直接写在参数定义的后面. function log(x, y = 'World') { console.log(x, y); } log('Hello') // ...

  7. ES6中箭头函数的作用

    我们知道在ES6中,引入了箭头函数,其本质就是等同有ES5中的函数.类似于下面的写法: let test1=() => “abc”; let test2=() => { return “a ...

  8. ES6中箭头函数与普通函数this的区别

    普通函数中的this: 1. this总是代表它的直接调用者, 例如 obj.func ,那么func中的this就是obj 2.在默认情况(非严格模式下,未使用 'use strict'),没找到直 ...

  9. ES6中对数组的扩展

    hello,大家好,我又来了.         前面讲了字符串和数值的扩展,今天要讲的是:数组的扩展.不知道大家能否跟得上这个节奏,你们在阅读中对讲解有存在疑惑,记得留言提出来,要真正地理解,否则白白 ...

随机推荐

  1. 感知器基础原理及python实现

    简单版本,按照李航的<统计学习方法>的思路编写 数据采用了著名的sklearn自带的iries数据,最优化求解采用了SGD算法. 预处理增加了标准化操作. ''' perceptron c ...

  2. iOS 协议分发

    Github:AOMultiproxier.HJProtocolDispatcher 协议实现分发器,能够轻易实现将协议事件分发给多个实现者. 一.AOMultiproxier.h #define A ...

  3. Java 异常处理与输入输出

    一.异常 1.1 package exception; import java.util.Scanner; public class ArrayIndex { public static void m ...

  4. window部署ftp服务器

                                                                                                         ...

  5. Jmeter 压力测试笔记(3)--脚本调试/签名/cookie/提升吞吐量/降低异常率/提升单机并发性能

    import XXXsign.Openapi2sign;---导入jar包中的签名方法 String str1 = "12121"; ---需要被签名的字段:向开发了解需要哪些哪些 ...

  6. php--phpstudy更新数据库版本后,无法一键启动

    只需输入以下命令即可: sc delete mysql

  7. [一起面试AI]NO.5过拟合、欠拟合与正则化是什么?

    Q1 过拟合与欠拟合的区别是什么,什么是正则化 欠拟合指的是模型不能够再训练集上获得足够低的「训练误差」,往往由于特征维度过少,导致拟合的函数无法满足训练集,导致误差较大. 过拟合指的是模型训练误差与 ...

  8. Hadoop(九):Shuffle组件

    重温MR整体流程 工作流程 开始执行输入(InputFormat),先对文件进行分片,然后读取数据输入到Map中. Mapper读取输入内容,解析成键值对,1行内容解析成1个键值对,每个键值对调用一次 ...

  9. java编写规范

    编码规范 转载于:https://www.cnblogs.com/ftl1012/p/javaCode.html 1 前言为确保系统源程序可读性,从而增强系统可维护性,java编程人员应具有基本类似的 ...

  10. js骚操作骂人不带脏

    前言 很多小伙伴们觉得javaScript很简单,下面的这行 javaScript代码可能会让你怀疑人生. (!(~+[])+{})[--[~+""][+[]]*[~+[]] + ...