1. 程式人生 > >ES6函數的擴展

ES6函數的擴展

return 回顧 多個參數 sum 又是 const 被調用 rest 傳參

參數的默認值

在開發中,給函數的參數指定默認值,是很普遍很常見的一個需求,我們先來回顧一下傳統的實現方式,對比著看更好理解:

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表示函數體;也許大家跟我一樣,很不習慣,但這種寫法確實簡潔了很多。

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參數、擴展運算符(...)以及箭頭函數。它們有一個共同的有點就是:使得代碼更加簡潔,結合需求靈活使用,可以大大地提高開發效率。

ES6函數的擴展