JavaScript 核心觀念(35)-函式以及 This 的運作-什麼是函式

前言

接下來是新的章節,而且這章節有萬惡的 this 呢!

函式

在開始這個章節之前,我會建議記得一個觀念,JavaScript 是由滿滿的物件所組成的,為什麼這樣講呢?在 「JavaScript 核心觀念(24)-物件-物件與純值」有驗證過一個觀念,我們其實也可以針對函式給予一個屬性。

那麼我們回頭看一下一個函式結構可以是什麼樣子

1
2
3
4
5
6
7
8
function fn(item) {
var a = 'Ray';
console.log(item);
return a + item;
}

var hello = fn('Hello');
console.log(hello);

首先函式會透過關鍵字 function 來定義宣告一個函式並搭配名稱組合,除此之外函式可以傳入參數並有屬於自己的程式碼區塊以及作用域也就是執行環境

1
2
3
4
function name(item) {
... // 程式碼片段
var a = 'Ray';// 區域變數
}

除此之外函式也具有被呼叫的能力 var hello = fn('Hello');,當然函式的特色還有一個,也就是可以撰寫程式碼的地方以及剛剛沒有提到的,它有屬於自己的 this

1
2
3
function fn(item) {
console.log(this);
}

這邊簡單整理一下函式具有什麼特色

  • 具有被呼叫的能力
  • 可以撰寫程式碼的區塊
  • 有屬於自己的 this
  • 具有自己的執行環境
  • 可回傳結果(return)
  • 名稱(選用,也就是匿名函式與具名函式)

函式表達式與函式陳述式

表達式與陳述式最簡單的判斷方式就是看它會不會回傳,因此函式陳述式的寫法我們在前面已經有寫過

1
2
3
function fn() {
...
}

函式陳述式最簡單的它並不會主動回傳結果給你,而是必須等你呼叫了他才會給予你結果,而表達式呢?

1
2
3
var fn = function() {
...
}

函式表達式在你程式碼執行時,就會將函式回傳到 fn 中,以上這邊觀念都與先前JavaScript 核心觀念(11)-運算子、型別與文法-陳述式與表達式相同,而這一段又稱之為匿名表達式,也就是沒有名稱的函式,但這邊要注意並不是所有函式表達式都是沒有名稱的。

以下範例就是具有名稱的函式表達式

1
2
3
var fnA = function fnB() {
...
}

而這個具有名稱的函式表達式有一個特點,函式本身的名稱只能在自己裡面呼叫,而不能在外面呼叫

1
2
3
4
var fnA = function fnB() {
...
}
console.log(fnA,fnB); // fnB is not defined

最後匿名函式與具名函式的使用時機與情境是什麼時候呢?以這一段來講其實滿看重開發團隊習慣的,如果是拿 Airbnb 規範來講其實會希望你盡可能不要使用函式陳述式,最主要原因在於 JavaScript Hoisting 會導致 Debug 的困擾,當然也有另一派說法是只要你能夠掌握 Hoisting 觀念,其實使用具名函式還是匿名函式都是可以的,因此使用函式表達式確實可以減少程式碼除錯的難度,在實際開發上有時候「提升」的問題會導致我們在排除錯誤時還要先思考一下整體流程是如何運作而導致無法確認問題點,但如果還是要使用函式陳述式的話也是可以,只是會建議必須在呼叫這個函式之前就宣告該陳述式,以確保函式已經被建立

1
2
3
4
function fn () {
}

fn();

參考文獻