今天是JavaScript學習紀錄的Day5,今天要來聊聊「函式」!
函式就像是我們常常會重複用到的小工具,把它包裝起來以後,就能隨時呼叫,省時又省力。
今日的目標:
在 JavaScript 裡,函式有兩種常見的寫法:
函式宣告(Function Declaration)
function sayHi() {
console.log("哈囉!");
}
sayHi(); // 直接呼叫
函式表達式(Function Expression)
const sayHello = function() {
console.log("你好!");
};
sayHello();
ES6 開始出現的箭頭函式(=>),讓程式看起來更簡潔。
const add = (a, b) => a + b;
console.log(add(2, 3)); // 5
箭頭函式沒有自己的 this,這點在物件導向或事件處理時特別重要。
為什麼要這樣設計?
JavaScript 設計箭頭函式時,主要是為了解決「巢狀函式」或「callback」裡 this 常常搞混的問題。
傳統寫法:一般函式的 this → 執行時才決定,看「誰呼叫它」。
function Timer() {
this.count = 0;
setInterval(function() {
this.count++; // 錯誤!這裡的 this 呼叫者不是 Timer,是 setInterval 的內部機制(window)
console.log(this.count);
}, 1000);
}
new Timer();
這段程式碼沒有操作到 Timer 裡的 count,而是誤操作到全域
所以this.count++ 嘗試在 window 上找 count,結果會是 undefined。
用箭頭函式:因為自己本身沒有this,他會繼承外層 this,使用上更直覺:
function Timer() {
this.count = 0;
setInterval(() => {
this.count++; // 正確!繼承 Timer 的 this
console.log(this.count);
}, 1000);
}
new Timer();
一般函式:this 跟「誰呼叫它」有關
箭頭函式:this 跟「它在哪裡被定義」有關
有時候函式會遇到沒有傳參數的情況,這時就能設定「預設值」。
function greet(name = "陌生人") {
console.log(`哈囉,${name}`);
}
greet(); // 哈囉,陌生人
greet("小明"); // 哈囉,小明
函式不只會執行事情,也可以「回傳結果」。
function multiply(x, y) {
return x * y;
}
let result = multiply(3, 4);
console.log(result); // 12
純函式就像是數學公式,不會偷偷改變外部的東西(沒有副作用)
輸入一樣 → 輸出一定一樣
function pureAdd(a, b) {
return a + b; // 只依賴輸入
}
相反的,不純函式會:
let total = 0;
function addToTotal(x) {
total += x; // 修改外部變數 → 有副作用
return total;
}