函數(shù)的擴(kuò)展
?????????? 函數(shù)參數(shù)的默認(rèn)值基本用法:
?????????? (1)ES6?之前,不能直接為函數(shù)的參數(shù)指定默認(rèn)值,只能采用變通的方法。

```
?????????? (2)與解構(gòu)賦值默認(rèn)值結(jié)合使用

```
??? ? ? ?? (3)參數(shù)默認(rèn)值的位置?
?????? 通常情況下,定義了默認(rèn)值的參數(shù),應(yīng)該是函數(shù)的尾參數(shù)。因?yàn)檫@樣比較容易看出來,到底省略了哪些參數(shù)。如果非尾部的參數(shù)設(shè)置默認(rèn)值,實(shí)際上這個(gè)參數(shù)是沒法省略的。


```
?????????? (4)函數(shù)的?length?屬性
??????? 指定了默認(rèn)值以后,函數(shù)的`length`屬性,將返回沒有指定默認(rèn)值的參數(shù)個(gè)數(shù)。也就是說,指定了默認(rèn)值后,`length`屬性將失真。
??????? (function?(a)?{}).length?? //?1
??????? (function?(a?=?5)?{}).length?? //?0
??????? (function?(a,?b,?c?=?5)?{}).length?? //?2

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

?????? 5.1代碼中,參數(shù)`y`的默認(rèn)值等于變量`x`。調(diào)用函數(shù)`f`時(shí),參數(shù)形成一個(gè)單獨(dú)的作用域。在這個(gè)作用域里面,默認(rèn)值變量`x`指向第一個(gè)參數(shù)`x`,而不是全局變量`x`,所以輸出是`2`。
```

??????? 5.2代碼中,函數(shù)`f`調(diào)用時(shí),參數(shù)`y?=?x`形成一個(gè)單獨(dú)的作用域。這個(gè)作用域里面,變量`x`本身沒有定義,所以指向外層的全局變量`x`。函數(shù)調(diào)用時(shí),函數(shù)體內(nèi)部的局部變量`x`影響不到默認(rèn)值變量`x`。
```

?????? 5.3代碼中,參數(shù)`x?=?x`形成一個(gè)單獨(dú)作用域。實(shí)際執(zhí)行的是`let?x?=?x`,由于暫時(shí)性死區(qū)的原因,這行代碼會(huì)報(bào)錯(cuò)”x?未定義“。
```

??????? 5.4如果將`var?x?=?3`的`var`去除,函數(shù)`foo`的內(nèi)部變量`x`就指向第一個(gè)參數(shù)`x`,與匿名函數(shù)內(nèi)部的`x`是一致的,所以最后輸出的就是`2`,而外層的全局變量`x`依然不受影響。

```
??????????? (6)rest?參數(shù)?
??????? ES6?引入?rest?參數(shù)(形式為`...變量名`),用于獲取函數(shù)的多余參數(shù),這樣就不需要使用`arguments`對(duì)象了。rest?參數(shù)搭配的變量是一個(gè)數(shù)組,該變量將多余的參數(shù)放入數(shù)組中。

`arguments`對(duì)象不是數(shù)組,而是一個(gè)類似數(shù)組的對(duì)象。所以為了使用數(shù)組的方法,必須使用`Array.prototype.slice.call`先將其轉(zhuǎn)為數(shù)組。rest?參數(shù)就不存在這個(gè)問題,它就是一個(gè)真正的數(shù)組,數(shù)組特有的方法都可以使用。下面是一個(gè)利用?rest?參數(shù)改寫數(shù)組`push`方法的例子。

???????? 注:rest?參數(shù)之后不能再有其他參數(shù)(即只能是最后一個(gè)參數(shù)),否則會(huì)報(bào)錯(cuò)。
??????????????????? //?報(bào)錯(cuò)
??????????????????? function?f(a,?...b,?c)?{
?????????????????????????? //?...
??????????????????? }
????????? 注:函數(shù)的`length`屬性,不包括?rest?參數(shù)。
???????????????? (function(a)?{}).length??//?1
???????????????? (function(...a)?{}).length??//?0
???????????????? (function(a,?...b)?{}).length??//?1
```
?????????? (7)嚴(yán)格模式
??????????????????? 從?ES5?開始,函數(shù)內(nèi)部可以設(shè)定為嚴(yán)格模式。ES2016?做了一點(diǎn)修改,規(guī)定只要函數(shù)參數(shù)使用了默認(rèn)值、解構(gòu)賦值、或者擴(kuò)展運(yùn)算符,那么函數(shù)內(nèi)部就不能顯式設(shè)定為嚴(yán)格模式,否則會(huì)報(bào)錯(cuò)
????????? (8)name?屬性?
?????????????????? 返回函數(shù)名:
?????????????????????????? function?foo()?{}
?????????????????????????? console.log(foo.name) ? //? foo
?????????????????????????? var?f?=?function?()?{};
?????????????????????????? console.log(f.name)?? //? f
```
??????????? (9)箭頭函數(shù)基本用法
???????????????? ES6?允許使用“箭頭”(`=>`)定義函數(shù)。
???????????????? 例如:var?fn =?v?=>?v;?? 箭頭函數(shù)等同于:var?fn =?function(v)?{return?v;};
?????????????? 注:如果箭頭函數(shù)不需要參數(shù)或需要多個(gè)參數(shù),就使用一個(gè)圓括號(hào)代表參數(shù)部分。

```
?????? 如果箭頭函數(shù)的代碼塊部分多于一條語句,就要使用大括號(hào)將它們括起來,并且使用`return`語句返回。
??????? var?sum?=?(num1,?num2)?=>?{?return?num1?+?num2;?}
```
?????? 由于大括號(hào)被解釋為代碼塊,所以如果箭頭函數(shù)直接返回一個(gè)對(duì)象,必須在對(duì)象外面加上括號(hào),否則會(huì)報(bào)錯(cuò)。
??????? //?報(bào)錯(cuò)
??????? let?getTempItem?=?id?=>?{?id:?id,?name:?"Temp"?};
??????? //?不報(bào)錯(cuò)
?????? let?getTempItem?=?id?=>?({?id:?id,?name:?"Temp"?});
```
箭頭函數(shù)使用注意點(diǎn):
1.?函數(shù)體內(nèi)的`this`對(duì)象,就是定義時(shí)所在的環(huán)境,而不是使用時(shí)所在的環(huán)境。
2.?不可以當(dāng)作構(gòu)造函數(shù),也就是說,不可以使用`new`命令,否則會(huì)拋出一個(gè)錯(cuò)誤。
3.?不可以使用`arguments`對(duì)象,該對(duì)象在函數(shù)體內(nèi)不存在。如果要用,可以用?rest?參數(shù)代替。
4.?不可以使用`yield`命令,因此箭頭函數(shù)不能用作?Generator?函數(shù)。
`this`指向的固定化,并不是因?yàn)榧^函數(shù)內(nèi)部有綁定`this`的機(jī)制,實(shí)際原因是箭頭函數(shù)根本沒有自己的`this`,導(dǎo)致內(nèi)部的`this`就是外層代碼塊的`this`。正是因?yàn)樗鼪]有`this`,所以也就不能用作構(gòu)造函數(shù)。
箭頭函數(shù)轉(zhuǎn)成?ES5?的代碼如下:

轉(zhuǎn)換后的?ES5?版本清楚地說明了,箭頭函數(shù)里面根本沒有自己的this,而是引用外層的this。
```
由于箭頭函數(shù)沒有自己的`this`,所以當(dāng)然也就不能用`call()`、`apply()`、`bind()`這些方法去改變`this`的指向。
```
????????? (10)函數(shù)參數(shù)的尾逗號(hào)
???????????? ES2017?[允許](https://github.com/jeffmo/es-trailing-function-commas)函數(shù)的最后一個(gè)參數(shù)有尾逗號(hào)(trailing?comma)。
?????? 這樣的規(guī)定也使得,函數(shù)參數(shù)與數(shù)組和對(duì)象的尾逗號(hào)規(guī)則,保持一致了。
