1.函数的默认值javascript
从ES6开始,容许为函数参数设置默认值,即直接写在参数定义的后面。这样作使代码变得简洁天然,另外还有两个好处:java
另外,参数变量是默认声明的,所以不能再使用let和const命令再次声明。定义了默认值的参数应该是函数的尾参数,这样就能够很容易的看出到底省略了哪些参数。若是尾部参数没有设置默认值那么是没法省略的。另外也没法直接省略处在中间的有默认值的参数,除非显示传入undefinednode
与解构赋值结合使用 编程
function m1({x:0,y:0} = {}){ return [x, y]; } function m2({x,y} = {x:0,y:0}){ return[x, y]; } m1()//[0,0] m2();//[0,0] m1({x:3, y:8});//[3,8] m2({x:3,y:8});//[3,8] m1({x:3});//[3,0] m2({x:3});//[3, undefined]
length属性数组
指定默认值之后函数的length属性返回的是没有指定默认值参数的个数,由于length属性的含义就是函数预期传入参数的个数,当某个参数指定了默认值之后预期的传入参数就再也不包括已经指定默认值的参数。app
ES6引入rest参数(形式为’…变量名’),用于获取函数的多余参数,该功能相似于Java中的不肯定数量的参数,rest参数将不定个数的参数转换为名称为指定变量名的数组,而后咱们能够经过众多的数组函数对其进行操做
注意一点,rest函数必须是函数的最后一个参数不然会报错函数式编程
与rest参数相反,扩展运算符 … 将一个数组转为用逗号分隔的参数序列。扩展运算符提供了众多的用途
替代数组的apply方法 函数
//ES5 Math.max.apply(null,[14,2,4]); //ES6 Math.max(...[14,2,4]);
合并数组优化
var arr1 = ['a', 'b']; var arr2 = ['c', 'd']; var arr3 = ['e']; //ES5 arr1.contact(arr2,arr3); //ES6 [...arr1, ...arr2, ...arr3];//['a', 'b', 'c', 'd', 'e']
与解构赋值结合
二者能够结合使用生成数组this
const [first, ...rest] = [1, 2, 3, 4, 5]; first //1 rest //[2,3,4,5]
将字符串转为数组
[..."hello"]// ['h', 'e', 'l', 'l', '0']
转换相似数组的对象、Set、Map以及Generator函数、
//转换对象 var nodelist = document.querySelectorAll('div'); var array = [...nodelist] //转换Map。Map和Set都是具备Iterator的对象, 只要是具备Iterator接口的对象均可以使用扩展运算符 let map = new Map([ [1, 'one'], [2, 'two'], [3, 'three'], ]); let arr = [...map.keys()];//[1, 2, 3] //转换Generator函数,Generator函数运行后返回一个遍历器对象,所以也可使用扩展运算符 var go = function*(){ yield 1; yield 2; yield 3; };
函数的name属性返回函数名,若是是匿名函数,ES5返回空字符串,而ES6返回实际的函数名。Function构造函数返回的函数示例name属性值为’anonymous’,bind返回的函数name属性值会加上’bound’前缀
var func1 = function(){}; func1.name;//ES5:"" ES6:func1 //若是将一个具名函数返回给一个变量,ES5/ES6都会返回这个具名函数本来的名字而不是变量名 const bar = function baz(){}; bar.name();//baz
ES6容许使用* 箭头 => *定义函数,箭头左边为参数,右边为方法体。若是不须要参数则用圆括号表明参数部分,若是方法体多于一行则用大括号括起来并用return表示返回。
var f = v => v; //等价于 var f = function(v){ return v}; var f = ()=>5; //等价于 var f = function(){ return 5; }
箭头函数的几点注意:
* 函数体内的this老是该函数定义时所在的对象。由于箭头函数根本没有本身的this,所以其内部的this就是外层代码块的this
* 不能够当作构造函数,即不可使用new命令
* 不可使用arguments对象,该对象在函数体内不存在, 能够用rest代替
* 不可使用yield命令,所以箭头函数没法用做Generator函数
ES7提出了函数绑定用来取代call、apply、bind调用,运算符是双冒号* :: *, 其坐标是一个对象,右边是一个函数,它将自动将左边的对象做为上下文环境(即this对象)绑定到右边的函数中。其返回的仍是原对象所以可使用链式调用
尾调用优化
尾调用是函数式编程的一个重要概念, 指某个函数的最后一步是调用另外一个函数。尾调用能够不出如今尾部,只要是函数操做的最后一步便可。
在函数的调用过程当中,会造成调用栈,尾调用与其余的调用不一样在于由于尾调用是函数的最后一步操做,所以不须要外层函数的调用栈,这样就只保留了内层的调用栈。所以若是全部的函数都是尾调用那么彻底能够作到每次执行调用时只有一帧,将大大的节省内存,这就是所谓的尾调用优化
尾调用能够对递归进行优化。函数调用自身成为递归,若是尾调用自身就成为尾递归。由于可能须要保存大量的调用栈所以很是消耗内存。尾递归很好的解决了这一问题。
尾递归的实现每每须要改写递归函数,确保其最后只调用自身。方法就是:把全部用到的内部变量变为函数的参数。但这么作会致使函数的可读性下降,这里有两个方法解决:
一是在尾递归函数以外再提供一个正常形式的函数来调用尾递归函数,另外一个就是柯里化,是函数式编程的一个概念,是将多参数的函数转换为单参数的形式。
尾逗号
从ES6开始容许函数的最后一个参数有尾逗号
function func( foo, bar,){ }