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,){ }