函數是可重複使用的程式碼區塊,用於執行特定任務或計算,你可以將它視為機器,它可以接受一些變數作為參數,並對其進行一些操作,接著產生輸出。
function functionName(parameters) {
// 函式內容
return value; // 可選,回傳值,如果沒有的話,預設會傳回 undefined
}
範例:
function greet() {
console.log("Hello");
}
greet() //呼叫函數,輸出 "Hello"
範例二:
// 傳入參數的函數
function greet(name) {
return `Hello, ${name}!`;
}
console.log(greet("Alice")); // "Hello, Alice!"
console.log(greet("Bob")); // "Hello, Bob!"
我們也可以替參數設置默認值,如果調用函數時沒有提供參數,則使用這些默認值。
function mystery(a, b = 3) {
return a * b;
}
console.log(mystery(4)); // 12
console.log(mystery(4, 4)); // 16
更簡潔的函數語法。像是將函數作為表達式賦值給變數。
語法:
const functionName = (parameters) => {
// 函數內容
return value; // 可選
};
範例:
const multiply = (a, b) => a * b;
console.log(multiply(4, 5)); // 20
x => x * x
{}
括號和 return
可以省略。好,這邊我要提到一個觀念: 作用域(Scope),其是指變數、函式或物件在程式中的可見範圍和存取範圍。理解作用域是掌握程式設計中變數生命週期與可訪問性的重要基礎。
範例:
let globalVar = "I am global";
function showGlobal() {
console.log(globalVar); // 可存取 globalVar
}
showGlobal(); // "I am global"
console.log(globalVar); // "I am global"
範例:
const myFunction = () => {
let localVar = "I am local";
console.log(localVar); // "I am local"
}
myFunction();
//console.log(localVar); // 錯誤:localVar is not defined
不過若是在函數內部定義一個同名變數,則以函數作用域的變數優先。
let Var = "I am global";
const myFunction = () => {
let Var = "I am local";
console.log(Var); // "I am local"
}
myFunction();
console.log(Var);
/* 輸出
I am local
I am global
*/
另外,請觀察以下程式碼:
if (true) {
let blockVar = "Hello";
}
console.log(blockVar); // ReferenceError: blockVar is not defined
ReferenceError: blockVar is not defined
,主要原因是 let
具有 區塊作用域 (block scope),而變數 blockVar
在 if
區塊內聲明,導致它無法在區塊外部存取。在 JavaScript 中,let
和 const
宣告的變數 只在其所在的區塊 (block) 內有效,而區塊指的是用 {}
包起來的程式碼範圍,例如 if
、for
、while
或一般 {}
。
在本例子中,變數 blockVar
只在 if
區塊 { }
內有效,當 console.log(blockVar);
嘗試在區塊外存取 blockVar
時,因為變數作用範圍已經結束,所以拋出 ReferenceError
。
相較之下,var
沒有區塊作用域,只有函式作用域。如果改用 var
,變數就能夠在區塊外存取:
if (true) {
var blockVar = "Hello"; // `var` 沒有區塊作用域
}
console.log(blockVar); // "Hello"
var
會提升 (hoist) 到最接近的函式作用域內,所以它即使是在 if
區塊內宣告,仍然能夠在 if
外部存取。var
的 Hoistingfunction example() {
console.log(a); // undefined (變數已提升,但未賦值)
var a = 10;
console.log(a); // 10
}
example();
發生了什麼?
var a
提升到函式的最上方,但 不會提升賦值部分,所以第一個 console.log(a);
會印出 undefined
,而不是錯誤。javascript複製編輯function example() {
var a; // 變數提升 (Hoisting)
console.log(a); // undefined
a = 10; // 賦值
console.log(a); // 10
}
var
可以在宣告前使用,但只會是 undefined
,因為它 只有變數名稱被提升。而Hoisting 在 if
和 {}
內的影響:
if (true) {
var x = 100;
}
console.log(x); // 100 (因為 `var` 沒有區塊作用域)
等價於:
var x; // 提升到最上方
if (true) {
x = 100;
}
console.log(x); // 100
不過,現代 JavaScript 幾乎不用 var
(其行為容易導致錯誤),主要是用 let
和 const
。