第十节:ES6为函数做了哪些扩展?
????????ES6一路擴展,字符串、數組、數值、對象無一“幸免”,ES6說要雨露均沾,函數也不能落下,今天,就來講解ES6對函數的擴展。
????????姿勢準備好了嗎?前方高能,第10節開講......
參數的默認值
????????在開發中,給函數的參數指定默認值,是很普遍很常見的一個需求,我們先來回顧一下傳統的實現方式,對比著看更好理解:
? ?function person(n,a){
??? ? ? var name = n || 'Zhangsan';
??? ? ? var age? = a ||? 25;
? ?}
? ?
????????上面是傳統的實現方式,通過或運算實現,原理:如果運算符 || 左側為true,直接返回左側的值,否則返回右側的值; 在person函數內,如果參數n沒有傳參,那么變量name得到的值就是“Zhangsan”,如果傳參了,變量name的值就為參數n的值。
????????但是,前提是參數對應的布爾值不能false(比如:數字0,空字符串等轉換成布爾值就是false),這就使得這種傳統的實現方式存在一定的不足和缺陷。
?
????????這個時候ES6說:“竟然這種寫法有缺陷,咱就不要用這種寫法了,我給你們帶來一種新的實現方式,比這種寫法好用多了,更簡捷”。
? ?function person(name = 'Zhangsan',age = 25){
?? ? ? console.log(name,age);
? ?}
? ?
? ?person();//結果:Zhangsan? 25
? ?person('Lisi',18);//結果:Lisi? 18
????????看,我們把默認值的設定放在了參數上:(name = 'Zhangsan',age = 25),這樣就實現了參數name的默認值為‘Zhangsan’,age的默認值為25。而不需要在函數體內進行檢測,函數體內可以專注對參數的使用或者運算,再也不用擔心函數的實際傳參情況了。
????????上面的案例,我們對person( )函數進行兩次調用,區別是有傳參數和沒傳參數,運行的結果也符合我們的預期:沒傳參,得到的是默認值Zhangsan 25,傳參就會得到傳入的參數值:Lisi ?18。
????????但是,多留個心眼,凡事總會有但是,如果函數有多個參數,但只有部分需要指定默認值,另一部分不需要的話,那么,設定默認值的參數一定要放在最后。看案例:
? ?//錯誤寫法
? ?function person(age = 25,name){
??? ? ? console.log(name,age);
? ?}
? ?
? ?//正確寫法
? ?function person(name,age = 25){
?? ? ? console.log(name,age);
? ?}
? ?
????????上面的person函數,兩個參數name和age,其中只有age需要指定默認值,name不需要,那么,age的排序就必須放在最后,name放在前面。也就是有默認值的參數后面不能再跟不需默認值的參數了。
????????另外,只有當傳入的參數為undefined,才會觸發默認值賦值。否則,哪怕你傳的參數值為0,false,null都不會觸發默認值賦值,這就完美的解決了傳統實現方式的弊端,試試看:
? ?function person(age = 12){
??? ? ? console.log(age);
? ?}
? ?
? ?person();//結果:12
? ?person(undefined);//結果:12
? ?person(0);//結果:0
? ?person(null);//結果:null
????????看person( )函數的4次調用和結果,只有不傳或者傳入undefined的時候才會觸發默認值賦值,得到12,傳入數字0或者null都不會觸發默認值賦值。
????????還有一個要注意的地方,函數的參數是默認聲明的,聲明過的變量,就不能用let或者const關鍵字再次聲明,否則會報錯的,不信給你看一個案例:
? ?function person(age = 12){
??? ? ? let age = 25;//錯誤,再次聲明age
? ?}
????????
????????上面這種情況,函數被調用后,就會報錯,會提示你age已經被聲明過了,你別再聲明它了。
rest參數
????????rest參數,這是一個新的概念,rest的中文意思是:剩下的部分。
????????如果用在函數上,就代表是獲取函數剩下部分的參數。具體是什么意思?我們還是得看案例才好理解,假設現在我們有這樣的一個需求:將一組數字進行求和,然后把求和的結果賦值到一個變量去,我們用rest參數實現:
? ?? ?//求和函數,得到的結果賦值到result
? ?function sum(result,...values){
??? ? ? //打印values看看是什么
??? ?console.log(values);
??? ? ? //結果:[1,2,3,4]
??? ? ? //進行求和
??? ?values.forEach(function (v,i) {
??????? ? ? //求和得到的結果存到result
??????? ? ? result += v;
??? ? ? });
??? ? ? //打印出求和的結果看看
??? ?console.log(result);
??? ? ? //結果:10
? ?}
? ?//存儲求和結果的變量res
? ?var res = 0;
? ?//調用sum函數
? ?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參數必須是函數的最后一個參數,后面不能再跟其他參數,什么意思呢?看案例:
? ?//錯誤寫法
? ?function sum(result, ...values, mult){
??? ? ? //rest參數...values后面還有一個參數mult
? ?}
? ?//正確的寫法
? ?function sum(result, mult, ...values){
??? ? ? //rest參數...values放在最后
? ?}
? ?
????????上面有錯誤和正確的兩種表示,在注釋上有說明原因。總之rest參數后面不能再跟有其他參數。
????????rest參數并不是適合所有的函數使用,只在特定的情境下會比較適用,比方說剛剛案例中的求和函數,就十分適合要rest參數把實際的參數收集起來放在數組中進行求和,在適當的情況下使用它可以事半功倍,減少代碼量,提高開發效率。?
擴展運算符
????????上面講到的rest參數,它的表示法使用...(三個點),它除了用在rest參數中,還有其他用途,我們稱這種表示法為擴展運算符,那么,它還有什么作用呢?
????????它一般結合數組使用,把數組的元素用逗號分隔開來,組成一個序列。我們看一下實際案例:
? ?function sum(a,b) {
?? ? ? return? a+b ;
? ?}
? ?let arr = [2,3];
? ?//用擴展運算法將數組[2,3]轉換成2,3?
? ?sum(...arr);
? ?//結果:5
????????上面的sum( )函數是簡單的將兩個數字相加求和,參數是兩個普通的參數x,y,并不是什么高逼格的rest參數,所以我們運用了擴展運算符...將數組[ ?2,3 ] 轉成了 2,3 兩個普通的數列,再傳進sum( )方法,對應上x,y兩個參數。實際上,sum( ...arr ) 的效果相當于sum( 2,3 ) 。
????????從這個案例我們就可以理解擴展運算符...的作用了,它可以將一個數組轉成一個對應的參數數列。在實際開發中,你可以根據擴展運算符的作用,可以靈活運用,實現各種效果。
?
箭頭函數
????????箭頭函數,這又是一個新概念,ES6給我們介紹一種全新的定義函數的方式,就是用箭頭符號(=>),故得名為箭頭函數。具體怎么用,我們來看案例:
? ?//傳統寫法
? ?var sum = function(a) {
?? ? ? return? a ;
? ?};
? ?
? ?//箭頭函數寫法
? ?var sum = a => a;
????????
????????什么?第二種寫法這么簡短.....不敢信!!
????????上面演示了兩種寫法,函數的作用都是一樣的,傳入參數a,直接返回a;第一種傳統的寫法大家都熟悉,我們看看第二種寫法:a=>a; 這里的第一個a代表是傳進去的參數,箭頭=>后面的a表示函數體;也許大家跟我一樣,很不習慣,但這種寫法確實簡潔了很多。
????????看到這里,有開發經驗的“老司機”可能會問:如果傳入的參數不止一個,或者函數體不是簡單的返回a,需要做一些其他的運算,含有多條語句的話,怎么辦?
????????問得好,對于這種情況,我們又有另一種處理辦法。舉個例子,假如我們給函數傳入2個參數,然后進行相加運算,我們用箭頭函數來實現:
? ?//箭頭函數寫法
? ?var sum = (a,b) => {return a+b}
? ?sum(1,2);//結果:3
????????注意上面的參數和函數體部分,如果參數超過1個的話,需要用小括號()括起來,函數體語句超過1條的時候,需要用大括號{ }括起來。
????????箭頭函數的最大作用就是簡化函數的實現,大大地減少代碼量。來舉個例子對比一下,假設我們現在要對一個數組 [ 1,2,3,4 ] 里面的數求和,我們分別用傳統的方式和箭頭函數都實現一次,大家看看差別:
? ?//傳統的寫法
? ?var sum = 0;
? ?[1,2,3,4].forEach(function(v){
??? ? ? sum += v;
? ?});
? ?
? ?//箭頭函數的寫法
? ?var sum = 0;
? ?[1,2,3,4].forEach(v => sum+=v);
????
????????大家對比一下,用箭頭函數代替了傳統的匿名函數,確實減少了代碼量。
?
????????今天講解的函數擴展都是一些新概念,新語法。也許你看懂了,但是過段時間會忘記,不用慌,這很正常,只有通過多練習、多使用才會記住。如果你現在的項目還未使用到這些知識的話,不妨先收藏起來,有空的時候翻看一下,也是很有幫助的,因為ES6是趨勢,總有一天會進入你的代碼中。
?
本節小結
總結:ES6為函數的擴展包括:參數的默認值、rest參數、擴展運算符(...)以及箭頭函數。它們有一個共同的有點就是:使得代碼更加簡潔,結合需求靈活使用,可以大大地提高開發效率。
總結
以上是生活随笔為你收集整理的第十节:ES6为函数做了哪些扩展?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [云炬创业基础笔记] 第四章测试5
- 下一篇: [云炬创业基础笔记] 第四章测试6