我們知道,函數是對象。每個函數 都是Function類型的實例,和其他引用類型一樣具有方法和屬性。由於函數是對象,因此函數名實際上是一個指向函數對象的指針。
函數有三種定義方式:函數聲明,函數表達式,使用Function構造函數。
函數聲明:
函數表達式:
在函數表達式中,使用變量sum即可引用函數,注意函數結尾有一個分號,就像聲明其他變量一樣。
構造函數(不推薦使用):
由於函數名僅僅是指向函數的指針,所以一個函數可以有很多的名字。注意使用不帶圓括號的函數名是訪問函數指針,而非調用函數。
在這里anotherSum和sum都指向了同一個函數。
1. 作為值的函數
由於JS中函數名本身就是變量,所以函數也可以作為值來使用。可以像傳遞參數一樣把函數傳遞給另一個函數,還可以把函數作為另一個函數的結果返回。
這個函數接受兩個參數,第一個是函數,第二個是函數的值
2. 函數的屬性和方法
每個函數都有兩個屬性:length和prototype,length表示函數希望接受到的參數的個數。對於prototype,它是保存JS引用類型所有實例方法的地方。
每個函數都有兩個非繼承而來的方法,apply和call方法。這兩個方法都是在特定的作用域中調用函數,實際上等於設置函體內的this對象的值。
這是apply和call方法真正強大的地方,可以擴充函數賴以執行的作用域。擴充作用域最大的好處就是對象不需要與方法有任何的耦合關系。
3. 匿名函數
顧名思義,匿名函數就是沒有實際名字的函數。因為沒有名字,所以我們需要找到方法去定位這個匿名函數。
1,以函數表達式的方式調用匿名函數,還有我們在DOM中常用的事件函數就是匿名函數。
→ 輸出:
匿名函數可以依附於一個變量,並且這個變量名就是這個匿名函數的名字。
2.我們在之前的文章說過,JS沒有塊級作用域。我們可以使用匿名函數來模仿塊級作用域。
3.如果將匿名函數放入到表達式中並且后面加上小括號會自動執行這個函數。
輸出:
輸出:
4. 如果一個自執行的匿名函數沒有返回值,將這個匿名函數賦值給一個變量的時候,這個變量的值是undefined。因為這個函數在賦值之前已經執行完了,而這個函數沒有返回值,所以就是undefined,如果有返回值,那么這個變量的值就是那個匿名函數的返回值。
輸出:
5.在outputNumbers函數中,我們在for循環外部插入了一個自運行的匿名函數,在匿名函數中定義的任何變量,都會在執行結束時被銷毀。因此變量i只能在循環中使用,使用完后即刻銷毀。