前言
介紹什麼是函式
函式
先看一下這個程式碼
// 函式結構
function afunction (parameter) {
var localVariable = '區域變數'; // this、區域變數
console.log(this, localVariable);
return '附加一段' + parameter; // 回傳、參數
}
var data = afunction('參數');
console.log(data);
這是一個函式陳述式,包含了 afunction 函式的名稱、 parameter 函式的參數、 this 函式的指稱、 localVariable 函式內
部的變數(區域變數)、 return 回傳值。又因為函式可以回傳值,讓這個呼叫的部分變成表達式,表達式的回傳值又可以賦予變
數內容,所以 var data = afunction('參數'); 這段才能成立
函式就是物件
函式就是物件,他跟物件的差別在於多了允許被呼叫的能力,例如:afunction( ) 以及能夠包含程式碼片段的能力 { }
上方的程式碼執行的結果我們可以看到如下
函式的名稱是刻在物件的屬性中,並且不能被覆寫的。如果撰寫函式陳述式的話,就必須要給予函式的名稱 ; 但如果是函式表達
式的話,則不一定需要名稱,這種情況就稱作匿名函式。
另外,函式的參數可以接受在被呼叫的地方傳入的資料,做一些處理。 this 這邊先有印象就好,之後會再後面的篇章介紹。
區域變數也只能在函式內調用,在函式的 { } 以外的地方無法被調用。回傳值可以回傳任何資料型態的資料,傳值就傳值,
傳物件就傳參考。
函式跟名稱之間的關係
之前我們有介紹過函式的陳述式以及表達式,除了寫法不同外,在 hoisting 的時候,被寫入記憶體的順序也不同,
我們可以看到下面這段程式碼:
function functionA () {
console.log('函式陳述式', '具名函式');
console.log(functionA);
}
functionA();
var functionB = function () {
console.log('函式表達式', '匿名函式');
console.log(functionB);
}
functionB();
functionA 是利用函式陳述式撰寫的具名函式。functionB 則是利用函式表達式撰寫的匿名函式。
呼叫方式則個別是 functionA( ) 以及 functionB( ) ,但事實上 functionB 並不是後面的匿名函式的函式名稱
我們來看看結果
我們可以看到 functionB 印出來之後的函式名稱是空的,所以其實利用這樣的函式表達式寫入到變數的 functionB ,
其實也是把後面的匿名函式的記憶體參考位置給傳入 functionB 中,並且利用 functionB( ) 的方式進行呼叫。
再提到另一個觀念就是,函式表達式後面的函式不一定是要匿名的!
來看一個範例
var functionC = function functionD () {
console.log(functionC, functionD);
}
functionC();
咦!我們明明是印出 functionC 以及 functionD,但其實他們的函式名稱都是 functionD,
所以也驗證了剛剛提到的,functionB 並不是後面函式的函式名稱這個概念。
另一個重點就在於,這個 functionD 的呼叫,只能在 functionD 的 { } 這個 scope 內,在這個 scope 以外的地方,
就無法呼叫了 ! 就像下面的範例。
var functionC = function functionD () {
console.log(functionC, functionD);
}
functionD();
//Uncaught ReferenceError: functionD is not defined
什麼時候會用到函式表達式的函式是具名函式呢 ?
var num = 1;
var giveMeMoney = function giveMoreMoney (coin) {
num += 1;
console.log('執行giveMeMoney', num, coin);
return coin > 100 ? coin : giveMoreMoney(num * coin);
}
console.log(giveMeMoney(30));
我們可以看到這是一個可以逐漸增加錢的具名函式,等 coin 的數量超過 100 之後,才會回傳 coin 的數字,並且被印出來。
如果還沒超過 100 就會乘上一個不斷 +1 的基數再重新跑一次 giveMoreMoney 的函式。
所以可以預期它的結果應該是下面這樣