深入理解ES6之函式

weixin_33724059發表於2018-03-07

一:關於函式的引數:

可以接受任意數量的引數而無視函式宣告的引數數量是js函式的獨特之處。

1:引數預設值

ES6之前做法

function makeRequest(url,timeout,callback){
 timeout=timeout||2000;
 callback = callback||function(){}
}

但是這樣timeout如果設定為0,還是會使用預設值。因此更安全的方法是使用typeof來檢測型別。

function makeRequest(url,timeout,callback){
 timeout=(typeof timeout !=='undefined')?timeout:2000;
}

ES6做法

functiong makeRequest(url,timeout=2000,callback=functing(){}){}
//只有在傳入undefined或者不傳時才會使用預設值 如果引數是null不適用預設值
makeRequest("xxxx",undefined,null)//第一個"xxxx",第二個使用預設值2000,第三次使用null

2:arguments物件

function mixArgs(first,second = 'b'){
arguments.length = 1
first === arguments[0]   true;
second ===arguments[1]  false;//second='b', arguments[1]='undefined'
}
mixArgs(1);

arguments物件的值傳入後就不在改變永遠等於初始值。

3:預設參數列達式

function getValue(value){
return value+5;
}
//表示式中可以說使用之前的引數,但不能使用後面的引數
function add (first,second=getValue(first)){
}

4:不具名引數

arguments物件包含的是傳入的全部引數,有時候操作起來還是比較麻煩。
ES6通過引入剩餘引數,可以包括顯示宣告的其他引數。

function pick(obj,..keys){
}

1:剩餘引數只能發到最後
2:剩餘引數不能再物件的setter屬性中使用,因為setter被限定為只是用單個引數,而剩餘引數是不限定數量的。

二:塊級函式:

"use strict"
if(true){
console.log(type doSomething);// "function"
function doSomething(){}
doSomething();
}
console.log(type doSomething);//  "undefined" 如果是非嚴格模式這裡也會是"function"      

在嚴格模式下定義的塊級函式會被提升到塊級作用域的頂部。而在非嚴格模式下會被提升至全域性作用域,因此在程式碼塊外部依然可以使用。

"use strict"
if(true){
console.log(type doSomething);// "undefined"//函式表示式不能提升 因此這裡暫時性死區
let doSomething =  function(){}
doSomething();
}
console.log(type doSomething);//  "undefined" 

三:箭頭函式:

1:沒有this,super,arguments,也沒有new.target繫結,這些值由離箭頭函式最近的非箭頭函式來決定.

2:不嫩被使用new呼叫,箭頭函式沒有構造方法,使用new呼叫會報錯。

3:不能更改this

function createArrow(){ return ()=>argument[0]}
var arrowFunction = createArrow(5)
console.log(arrowFunction()) // 5

四:尾呼叫優化:

滿足三個條件es6在嚴格模式下會優化(非嚴格模式不變)
1:為呼叫不能引用當前棧幀的變數(意味著該函式不能是閉包)
2:進行尾呼叫的函式在返回結果後不能做額外操作
3:尾呼叫的結果作為當前函式的返回值

"use strict"
//不優化 沒有return
function doSomething(){
  doSomethingElse()
}

//不優化 返回後還要執行加法
function doSomething(){
  return 1+ doSomethingElse()
}

//不優化 呼叫未在尾部
function doSomething(){
  let res = doSomethingElse();
  return res;
}

//不優化 訪問內部變數
function doSomething(){
  let num = 1;
  let func = ()=>num; 
  return func();
}
function factorial(n){
  if(n<=1){
    return 1;
  } else{
  //不優化 返回後還要執行乘法
  return n*factorial(n-1);
 }
}

//優化後
function factorial(n,p=1){
 if(n<=1){
    return 1*p;
 }else{
   let result = n*p;
   return factorial(n-1,result);
 }
}

相關文章