[TOC]
* * * * *
### 一、什么是函數
> 函數是由事件驅動的或者當它被調用時執行的可重復使用的代碼塊。
- 語法
```JavaScript
function fun(arg1,arg2){
// 要執行的代碼塊
}
```
- 調用方式
第一種:事件驅動函數
```HTML
<button onClick="fun()">按鈕</button>
<script>
function fun(arg1,arg2){
// 要執行的代碼塊
}
</script>
```
第二種:調用函數
```JavaScript
function fun(arg1,arg2){
// 要執行的代碼塊
}
fun()
(function (arg1,arg2){
// 要執行的代碼塊
})()
```
### 二、函數需要了解的知識
1. 作用域
作用域分為全局作用域和局部作用域
全局作用域:供所有代碼執行的環境,只要瀏覽器不關閉就不會消失,也是最高的執行環境,在該作用域下聲明的變量為全局變量
局部作用域:函數執行的時候,開辟的用來解析函數體的代碼的新的棧內存,它也叫做私有作用域,在該作用域下聲明的變量為局部變量
```JavaScript
//變量a就處于全局環境下,它是全局變量
var a = 1;
function fun(){ // 函數fun 處于全局環境下
var b = 2; //變量b就處于局部環境下,它是局部變量
var a = 3; //變量a就處于局部環境下,它是局部變量
}
```
2. 變量
js中使用var聲明的東西才是變量,但是需要注意的是:
```JavaScript
var b = 1;
c = 1
```
這里變量b和c的區別是:
- b是變量而c不是變量,要注意的是在全局環境下,變量b和c都會被js引擎添加到window下作為其屬性,如果在局部變量下,當函數執行后變量不會被添加到window對象上作為其屬性。
- 變量b會在程序初始化是提升(變量提升原則),而c不會。
```JavaScript
console.log(a) // a為underfind,因為a變量初始化時被提升了
var a = 1;
console.log(a) // 1
```
### 三、函數聲明和函數表達式
1. 什么是函數聲明
> 有一個特定的名稱
> 在源碼中的位置:要么處于程序級(Program level),要么處于其它函數的主體>(FunctionBody)中
> 在進入上下文階段創建
> 影響變量對象
以下面的方式聲明
```JavaScript
function fun(){
}
```
上邊的函數就是以函數聲明方式創建的,有一個特定的名稱fun,處于全局環境,在進入上下文階段創建指的是程序開始運行時優先處理函數。影響變量對象可以看下面代碼:
```JavaScript
console.log(fun) // fun函數,這里是因為函數提優先于同名變量提升(其實是覆蓋了變量對象中的同名變量)
var fun = 111;
console.log(fun) //111
function fun(){
}
console.log(fun) //fun 函數
var fun = 222;
console.log(fun) //222
```
2. 函數表達式
> 在源碼中須出現在表達式的位置
> 有可選的名稱
> 不會影響變量對象
> 在代碼執行階段創建
最典型的就是匿名函數:
```JavaScript
var fun = function (){}
```
函數表達式其實也可以擁有函數名的:
```JavaScript
!function fun(){} // 這也是函數表達式
```
所以說函數表達式和函數聲明最主要的判斷依據是,看看函數主體function 最前邊是否含有其它東西(主要指運算符)。
例如常見表達式:
```JavaScript
+function fun(){
}
1,function fun(){
}
&function fun(){
}
(function(){})
var obj = {
fun:function(){}
}
```
### 四、立即自執行函數
程序一運行時,函數會立即自己調用自己的函數。常見的立即自執行函數:
```JavaScript
(function(a){
console.log(a) // 1
})(1)
(function(a){
console.log(a) // 1
}(1))
```
自執行函數還有沒有其他的寫法,其實是有的,我們只要知道立即自執行函數是怎么自調的就可以寫出很多,他的特點就是小括號 `()` 左邊只要是函數表達式,它就可以立即自調。
例如:
```JavaScript
+function fun(a){
console.log(a) // 1
}(1)
1,function fun(a){
console.log(a) // 1
}(1)
&function fun(a){
onsole.log(a) // 1
}(1)
```