淺談JavaScript中的特殊函式

語言: CN / TW / HK

theme: fancy highlight: atom-one-light


持續創作,加速成長!這是我參與「掘金日新計劃 · 6 月更文挑戰」的第28天,點選檢視活動詳情

Hi~,我是一碗周,如果寫的文章有幸可以得到你的青睞,萬分有幸~

🍑 寫在前面

JavaScript中的函式本質上是一個物件,我們可以將這個物件賦值給一個變數,這就使JavaScript中的函式變得非常的靈活,現在就來淺看一下JavaScript中函式的一些用法。

🍒 匿名函式

JavaScript 可以將函式作為資料使用。作為函式本體,它與普通的資料一樣,不一定有名字。沒有名字的函式被稱之為匿名函式。

示例程式碼如下:

javascript //匿名函式 function(){ //匿名函式,會報錯 return '一碗周'; }

但是在 JavaScript 並不支援匿名函式的語法,不過匿名函式有兩個應用,如下所示:

  • 回撥函式:將一個函式作為另一個函式的引數使用,作為引數的函式

  • 自調函式:函式呼叫自身(定義即呼叫的函式)

🍓 回撥函式

然函式與任何可以被賦值給變數的資料是相同的,那麼它當然可以像其他資料那樣被定義、刪除、拷貝,以及當成引數傳遞給其他函式。

當一個函式作為引數傳遞給另一個函式時,作為引數的函式被稱之為回撥函式。作為使用回撥函式的函式稱為目標函式(外層函式)

示例程式碼如下所示

```javascript // 定義一個函式,這個函式有兩個函式型別的引數,然後分別執行那兩個函式,並返回它們的和。 function sum(a, b) { // -> 目標函式 return a() + b() }

function one() { // -> 回撥函式 return 1; }

function two() { // -> 回撥函式 return 2; }

console.log(sum(one, two)); // 3 ```

執行流程如下:

當執行 sum 函式時,傳入兩個實參,在 sum 函式中,會將兩個實參作為函式執行,並將返回值計算並返回。

匿名回撥函式

所謂匿名回撥函式,就是目標函式中的引數是沒有名稱的函式,將上一段程式碼修改為使用匿名回撥函式

```javascript // 定義一個函式,這個函式有兩個函式型別的引數,然後分別執行那兩個函式,並返回它們的和。 function sum(a, b) { // -> 目標函式 return a() + b() }

console.log(sum( function () { // -> 匿名回撥函式 return 1 }, function () { // -> 匿名回撥函式 return 2 })); // 3 ```

帶引數的回撥函式

javascript function multiplyByTwo(a, b, c, callbakc) { var i, ar = [] for (i = 0; i < 3; i++) { // 通過 arguments 物件將傳入的引數 * 2,然後傳入回撥函式進行操作 ar[i] = callbakc(arguments[i] * 2); } return ar; } console.log(multiplyByTwo(1, 2, 3, function (a) { // 匿名回撥函式 return a + 2 }));

回撥函式的優點:

  • 匿名回撥函式節省了全域性名稱空間

  • 將私有的資料內容開放給指定位置使用

  • 保證封裝性 - 雖然可以使用私有資料,但是並不知道來源

  • 有助於提升效能

但是回撥函式也是有缺點的,當目標函式的引數是一個回撥函式時,回撥函式的引數又是另一個回撥函式,另一個回撥函式的引數還是一個回撥函式…也就是套娃,也就形成了回撥陷阱或稱回撥地獄

🫐 自調函式

目前我們已經討論了匿名函式在回撥方面的應用。接下來我們討論另外一種情況,即自調函式,這種函式可以在定義後立即呼叫。示例程式碼如下所示

javascript ( function () { console.log("自調函式"); } )()

這種語法看上去有點唬人,其實沒有什麼,我們只需將匿名函式的定義放進一對括號中,然後外面再緊跟一對括號即可。

語法結構如下圖所示

值得注意的是,自調函式可以命名,但是還是會自呼叫,如果用函式名呼叫的話會丟擲異常

自調函式除了以上兩種方式外,還有以下幾種不常用的方式

```javascript + function (v) { // 形參 var w = 100; // 區域性變數 console.log("自調函式" + v); }(1);// 實參

! function (v) { var w = 100; // 區域性變數 console.log("自調函式" + v); }(2);

~ function (v) { var w = 100; // 區域性變數 console.log("自調函式" + v); }(3); ```

使用即時自調匿名函式的好處是不會產生任何全域性變數。

缺點在於這樣的函式是無法重複執行的(除非將它放在某個迴圈或其他函式中)。這也使得即時函式非常適合於執行一些一次性的或初始化的任務。

🍊 作為值的函式

將一個函式作為另一個函式的結果並返回,作為結果返回的函式稱之為作為值的函式

示例程式碼如下:

javascript function outer() { var v = 100; // 在函式的函式體中定義另一個函式 -> 內部(私有)函式 return function () { // 使用匿名函式 return v * 2 } } var result = outer(); console.log(result); // [Function] // 或者下面這種方式與上面那種方式相同 function outer1() { var v = 100; // 在函式的函式體中定義另一個函式 -> 內部(私有)函式 function inner() { return v * 2 } return inner } var result1 = outer1(); console.log(result1); // [Function: inner]

這樣做的好處是:

  • 有助於我們確保全域性名字空間的純淨性(這意味著命名衝突的機會很小)。

  • 確保私有性 — 這使我們可以選擇只將一些必要的函式暴露給“外部世界”,而保留屬於自己的函式,使它們不為該應用程式的其他部分所用。

🍉 寫在最後

本篇文章中介紹了一些函式的特殊用法,也可以說是一些基礎用法吧,內容很簡單🤓🤓🤓🤓