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