自學日記

學習程式相關知識及學習法

0%

JS 基本函式Function概念

JS 基本函式(Function)概念

介紹函式、作用域及提升該念

何謂函式

“函式”指的是將一或多段程式指令包裝起來,可以重複使用,也方便維護。(參至 0陷阱!0誤解!8天重新認識javascript)

也就是指如果在程式內,多次使用到某程式碼時,可以統一整理,定義function,以方便之後如有更動,方便統一修改,不必個別修改。
EX:

1
2
3
4
5
for (var i = 1; i<10; i++){
console.log("第"+ i +"隻綿羊");
/*假若原本程式碼我們多次使用到此行,
那麼我們可以使用function方便我們做整理撰寫*/
}

定義function,修改後為:

1
2
3
4
5
6
7
8
function echoSheep(index){
console.log("第" + index + "隻綿羊");/*定義之後,
* 如有修改內容,從此function下手就可以!*/
}

for(var i = 1; i < 10; i++){
echoSheep(i)//以function定義,方便做統一修改
}

定義函式的方式

函式宣告(Function Declaration)

屬於最常見的用法:

1
2
3
function 名稱 ([參數1,參數2,...]){
//做某事
}

範例:

1
2
3
function square(namber){
return number * number;
}

初步認識函式陳述式(Function Statement)

從上面宣告方式也可以進一步去看關於陳述式的部分,
陳述式指的是:
藉由直接給定函式名稱來宣告一個函式,為一般函式宣告

初步認識函式表達式(或稱表示式)(Function Expressions)

表達式(表示式)為直接把一個函式指派給另一個變數,因此除了一般的宣告外,函式也能夠作為被指派的值。

範例:

1
2
3
var square = function (number) {
return number * number;
}

而以上範例可知,function後並沒有定義名稱,此為匿名函式,

如何撰寫函式

上述介紹完function形式後,我們以白話點的方式幫助我們日後撰寫function,首先前面提及函式指的是將一或多段程式指令包裝起來,可以重複使用,也方便維護。 意思為在一段程式碼中,我們需要判別哪些變數會在之後需要改變,

由以下a物品及b物品的價格及顧客要來購買的例子來解釋:

1
2
3
4
5
var aPrice = 5;//a價格
var bPrice = 4;//b價格
var Whobuytotal = aPrice + bPrice;//顧客買的總價格

console.log("ME" + MYbuytotal);//計算一個顧客買的價格

上述程式碼判斷,我們可以得知:

  1. a物品價格及b物品價格為不會改變的變數,
  2. 會改變的變因為: 顧客名、a、b物品數量,
  3. 確定完之後,我們需要計算每個顧客購買的總價格,因此設定function,讓他專門return給我們結果。
1
2
3
4
5
6
7
8
9
10
11
var aPrice = 5;
var bPrice = 4;
var Whobuytotal:
Whobuytotal = aPrice + bPrice;
//function名字(參數,參數,參數)
function buy(Name,aNum,bNum){
return Name+(aPrice * aNum + bPrice * bNum)
}

console.log("John",3,3);
console.log("BOB",4,5);

變數的有效範圍-作用域(scope)

Function是一個作用域,
舉例而言:

1
2
3
4
5
6
7
var a = 100;//為下方console.log(a)
function helloWorld(){
var a = 150;
console.log(a)//為下方helloWorld()
}
helloWorld();
console.log(a);

印出來的數字(a)為
150(helloWorld()的結果)
100(console.log(a)的結果)
由此結果可知function為作用域,前提為必須在function裡加上var or let,才不會污染其他變數。
必須注意,如果未加var,那剛才的程式運算結果將為
150
150

  • function 可以影響外層已經宣告的變數,但外層無法影響function內宣告的變數,因此,寫在函式(function)內,若無var、let、const的變數,會變成全域變數

P.S 全域變數與區域變數

function內為區域變數,外為全域變數,大至window,(window為根物件),而在JS內,全域變數更準確來說,應該為全域物件(或為頂層物件),以瀏覽器來說即為window,在node環境中則叫做global。

提升(Hoisting)

關於提升的概念,覺得比較明瞭的說法參考至卡斯伯-鐵人賽:JavaScript Function 與 Hoisting

提升比較類似於變數和函式的宣告先被放入記憶體,以上述引用的連結文章來說明,以白話說明,就像是一本筆記本列了多項要做的項目,但作者翻閱筆記本並不是要開始做,而是類似備忘錄的概念,先記在腦子裡,所以,
以文章中的舉例來說:

假如變數尚未被宣告,而使用console.log()印出,會顯示此變數未被定義。

1
1 console.log(phone); // phone is not defined

假如在var 定義變數前使用console.log(),那麼將會顯示undefined,表示已經存入記憶體,但尚未有值。

1
2
1 console.log(phone); // undefined
2 var phone = 'myphone';

也就是我們可以解讀為以下的樣子:

1
2
3
1 var phone;//只有宣告語法被存入記憶體之中
2 console.log(phone); // undefined
3 var phone = 'myphone';

因此,因為這樣變數提升的特性,請必須將變數都盡量在scope的最上面先宣告完成再使用。

let、const的暫時性死區

結論: 盡量不要再用var來宣告變數,改用let與const,而且優先使用const,除非需要再指定值才用let。

  • “ const ”— 一般使用在識別值(identifier)不會被重新指定值。
  • “let”— 一般使用在變數(variable)可能會被重新指定值。

引用參考資料至:
ES6篇 - let與const
JavaScript: var, let, const 差異