ES6語法——Function的擴(kuò)展

一、函數(shù)默認(rèn)參數(shù)
????????ES6 允許為函數(shù)的參數(shù)設(shè)置默認(rèn)值,即直接寫在參數(shù)定義的后面。

????????ES6中函數(shù)默認(rèn)值需要注意的點(diǎn)有:
????????(一)參數(shù)變量是默認(rèn)聲明的,所以不能用let或const再次聲明(說明參數(shù)的變量聲明是let聲明的)
????????(二)參數(shù)默認(rèn)值不是傳值的,而是每次都重新計(jì)算默認(rèn)值表達(dá)式的值。也就是說,參數(shù)默認(rèn)值是惰性求值的。

????????(三)在和解構(gòu)賦值默認(rèn)值一起使用的時(shí)候,需要注意這三種默認(rèn)值的不同。

????????(四)參數(shù)默認(rèn)值的位置:通常情況下,定義了默認(rèn)值的參數(shù),應(yīng)該是函數(shù)的尾參數(shù)。因?yàn)檫@樣比較容易看出來,到底省略了哪些參數(shù)。如果非尾部的參數(shù)設(shè)置默認(rèn)值,實(shí)際上這個(gè)參數(shù)是沒法省略的。
? ??????(五)觸發(fā)函數(shù)參數(shù)默認(rèn)值的條件是:參數(shù)的值===undefined? (兩種情況,一種是真的沒有傳值,一種是顯示傳入undefined)
? ??????(六)函數(shù)參數(shù)的length屬性:
? ? ? ? (1)指定了默認(rèn)值以后,函數(shù)的length屬性,將返回沒有指定默認(rèn)值的參數(shù)個(gè)數(shù)。也就是說,指定了默認(rèn)值后,length屬性將失真。
????????(2)如果設(shè)置了默認(rèn)值的參數(shù)不是尾參數(shù),那么length屬性也不再計(jì)入后面的參數(shù)了。

(七)參數(shù)作用域:一旦設(shè)置了參數(shù)的默認(rèn)值,函數(shù)進(jìn)行聲明初始化時(shí),參數(shù)會(huì)形成一個(gè)單獨(dú)的作用域(context)。等到初始化結(jié)束,這個(gè)作用域就會(huì)消失。這種語法行為, 在不設(shè)置參數(shù)默認(rèn)值時(shí),是不會(huì)出現(xiàn)的。

二、rest 參數(shù)
????????ES6 引入 rest 參數(shù)(形式為...變量名 ),用于獲取函數(shù)的多余參數(shù),這樣就不需要使用arguments對(duì)象了。rest 參數(shù)搭配的變量是一個(gè)數(shù)組,該變量 將多余的參數(shù)放入數(shù)組中。
????????rest 參數(shù)之后不能再有其他參數(shù)(即只能是后一個(gè)參數(shù)),否則會(huì)報(bào)錯(cuò)。
? ??????函數(shù)的length屬性,不包括 rest 參數(shù)。

三、箭頭函數(shù)
????????ES6標(biāo)準(zhǔn)新增了一種新的函數(shù):Arrow Function(箭頭函數(shù))

????????箭頭函數(shù)相當(dāng)于匿名函數(shù),并且簡(jiǎn)化了函數(shù)定義。箭頭函數(shù)有兩種格式,一種像上面的,只包含一個(gè)表達(dá)式,連{ ... }和return都省略掉了。還有一種可以包含多條語句,這時(shí)候就不能省略{ ... }和return
? ??????由于大括號(hào)被解釋為代碼塊,所以如果箭頭函數(shù)直接返回一個(gè)對(duì)象,必須在對(duì)象外面加上括號(hào),否則會(huì)報(bào)錯(cuò)。
? ??????箭頭函數(shù)的一個(gè)用處是簡(jiǎn)化回調(diào)函數(shù)

(一)箭頭函數(shù)——this問題
? ? ? ? (1)箭頭函數(shù)的this指向是詞法作用域,由上下文確定
? ? ? ? (2)箭頭函數(shù)的 this 始終指向函數(shù)定義時(shí)的 this,而非執(zhí)行時(shí)

? ? ? ? (2-1)上面的setTimeout定時(shí)器執(zhí)行時(shí)與函數(shù)環(huán)境脫離,調(diào)用其的對(duì)象是window,但是箭頭函數(shù)的this不是動(dòng)態(tài)作用域,而是詞法作用域,所以這個(gè)定時(shí)器里面的this還是指向obj,下面是定時(shí)器封裝正常的函數(shù)的情形:

? ? ? ? (2-2)這里打印出undefined的原因是:我編寫的環(huán)境是在node下的和瀏覽器環(huán)境還是有一定的區(qū)別,node環(huán)境下,最后調(diào)用這個(gè)定時(shí)器的是Timeout對(duì)象,所以this指向的是Timeout對(duì)象,但是這個(gè)對(duì)象上面沒有age屬性(我們定義的age屬性是定義在window上面的),所以打印出undefined了

? ? ? ? (2-3)不過在瀏覽器環(huán)境下運(yùn)行也還是需要注意的一個(gè)細(xì)節(jié)就是:let const聲明的變量和函數(shù)不會(huì)定義在window對(duì)象上了,也就是說不會(huì)成為window的屬性和方法了,但是var聲明的變量和方法聲明的變量和函數(shù)還是定義在window上的屬性和方法

????????(3)箭頭函數(shù)中沒有 this 綁定,必須通過查找作用域鏈來決定其值,如果箭頭函數(shù)被非箭頭函數(shù)包含,則 this 綁定的是最近一層非箭頭函數(shù)的 this,否則,this 為 undefined”。
????????(4)箭頭函數(shù)如果是多層嵌套,不管嵌套多少層,this都是通過查找作用域鏈來決定其值
????????(5)this就是函數(shù)作為方法被調(diào)用所屬的對(duì)象
(二)箭頭函數(shù)使用注意
(1)由于this在箭頭函數(shù)中已經(jīng)按照詞法作用域綁定了,所以,用call()或者apply()調(diào)用箭頭函數(shù)時(shí),無法對(duì)this進(jìn)行綁定,即傳入的第一個(gè)參數(shù)被忽略:

(2)不可以當(dāng)作構(gòu)造函數(shù),也就是說,不可以使用new命令,否則會(huì)拋出一個(gè)錯(cuò)誤。
(3)不可以使用arguments對(duì)象,該對(duì)象在函數(shù)體內(nèi)不存在。如果要用,可以用 rest 參數(shù)代替。
(4)不可以使用yield命令,因此箭頭函數(shù)不能用作 Generator 函數(shù)。
(5)除了this,以下三個(gè)變量在箭頭函數(shù)之中也是不存在的,指向外層函數(shù)的對(duì)應(yīng)變量:arguments、super、new.target

四、函數(shù)尾調(diào)用
? ? ? ? (一)定義:某個(gè)函數(shù)的后一步是調(diào)用另一個(gè)函數(shù)

? ??????(二)尾調(diào)用有什么用?
????????按照阮一峰大佬的解釋如下:
????????我們知道,函數(shù)調(diào)用會(huì)在內(nèi)存形成一個(gè)“調(diào)用記錄”,又稱“調(diào)用幀”(call frame)保存調(diào)用位置和內(nèi)部變量等信息。如果在函數(shù)A的內(nèi)部調(diào)用函數(shù)B,那 么在A的調(diào)用幀上方,還會(huì)形成一個(gè)B的調(diào)用幀。等到B運(yùn)行結(jié)束,將結(jié)果返回到A,B的調(diào)用幀才會(huì)消失。如果函數(shù)B內(nèi)部還調(diào)用函數(shù)C,那就還有一 個(gè)C的調(diào)用幀,以此類推。所有的調(diào)用幀,就形成一個(gè)“調(diào)用?!保╟all stack)。
?????????尾調(diào)用由于是函數(shù)的后一步操作,所以不需要保留外層函數(shù)的調(diào)用幀,因?yàn)檎{(diào)用位置、內(nèi)部變量等信息都不會(huì)再用到了,只要直接用內(nèi)層函數(shù)的調(diào)用幀,取代外層函數(shù)的調(diào)用幀就可以了。? ?????
? ? ? ? 尾調(diào)用可以改造遞歸調(diào)用,使其變成尾遞歸,以永遠(yuǎn)不會(huì)發(fā)生“棧溢出”錯(cuò)誤。要做的就是將原來的遞歸函數(shù),改寫為每一步返回另一個(gè)函數(shù)。
? ??????它的原理非常簡(jiǎn)單。尾遞歸之所以需要優(yōu)化,原因是調(diào)用棧太多,造成溢出,那么只要減少調(diào)用棧,就不會(huì)溢出。怎么做可以減少調(diào)用棧呢?就是采用“循 環(huán)”換掉“遞歸”。

五、小結(jié)
? ? ? ? ES6中函數(shù)的擴(kuò)展主要掌握的點(diǎn)是:函數(shù)的默認(rèn)參數(shù)、rest參數(shù)、箭頭函數(shù)以及其this問題、尾函數(shù)的調(diào)用以及給遞歸函數(shù)帶來的優(yōu)化

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 函數(shù)參數(shù)的默認(rèn)值 基本用法 在ES6之前,不能直接為函數(shù)的參數(shù)指定默認(rèn)值,只能采用變通的方法。 上面代碼檢查函數(shù)l...
    陳老板_閱讀 514評(píng)論 0 1
  • 函數(shù)參數(shù)的默認(rèn)值 基本用法 在ES6之前,不能直接為函數(shù)的參數(shù)指定默認(rèn)值,只能采用變通的方法。 上面代碼檢查函數(shù)l...
    呼呼哥閱讀 3,703評(píng)論 0 1
  • 1.函數(shù)參數(shù)的默認(rèn)值 (1).基本用法 在ES6之前,不能直接為函數(shù)的參數(shù)指定默認(rèn)值,只能采用變通的方法。
    趙然228閱讀 830評(píng)論 0 0
  • 今天是母親節(jié),顧名思義,即有孩子當(dāng)了媽媽了,所以今天祝自己節(jié)日快樂! 在此分享下做母親的點(diǎn)滴: 1.昨晚由于老公某...
    百合_c5c0閱讀 362評(píng)論 0 1
  • 一周集中看資料也是很累的事情。周日下雨,從白天睡到了晚上。起來時(shí)已經(jīng)是晚上八點(diǎn)多。下樓吃了點(diǎn)東西,稍微歇了會(huì)兒就又睡了。
    小王加油啊閱讀 277評(píng)論 0 0

友情鏈接更多精彩內(nèi)容