本系列內容是基於 Eloquent JavaScript 4th edition (2024) 所整理的精簡筆記。
The best programs are those that manage to do something interesting while still being easy to understand.

本文深入探討 JavaScript 的程式結構,從最基本的表達式和語句概念,到綁定、函式及控制流程的具體實現。通過實際的程式碼範例,說明如何有效地使用這些基本組件來組織程式碼,提升可讀和可維護性。同時也介紹了程式風格的最佳實踐,幫助開發者撰寫更清晰易懂的程式碼。
表達式(Expression)
表達式是一段能產生值的程式碼片段,無論這個值是數字、字串還是其他類型,都可以用於更複雜的運算或邏輯中。
- 例如:
22、"psychoanalysis"、1 + 1都是表達式。 - 表達式的功能類似於語言中的「句子片段」,它們是構成程式的基本組件,可以單獨存在,也可以組合成更複雜的計算。
語句(Statement)
語句是程式碼中的完整指令,通常用於執行某些動作,例如運算、輸出結果或改變程式的狀態。
語句與表達式的區別
- 表達式產生一個值,作為程式中的組件使用。
- 語句是一條完整的指令,用於執行動作,並可能對外界產生影響(副作用)。
副作用(side effects):指語句執行後,對程式或外部環境(如顯示輸出或修改變數)造成的影響。
範例
1; // 語句,沒有任何副作用。
console.log("Hello"); // 語句,具有副作用:在控制台顯示 "Hello"。
- 第一行是一條語句,它僅執行了一個表達式,沒有改變程式的狀態,因此沒有副作用。
- 第二行也是一條語句,執行後會在控制台輸出字串
"Hello",這是一種副作用。
綁定(Binding)
綁定是程式用來記住數值或狀態的一種方式。在 JavaScript 中,綁定通常以變數的形式實現。
綁定的作用在於儲存程式執行過程中的數值或狀態,例如:計算結果或用戶資料。如果沒有綁定,計算出的新值會立即消失,無法再被使用。
1. 綁定的基本操作
1.1 存取綁定
let caught = 5 * 5;
console.log(caught); // → 25
1.2 更新綁定
let mood = 'light';
console.log(mood); // → light
mood = 'dark';
console.log(mood); // → dark
2. let、var 和 const
2.1 let
- 現代 JavaScript 中創建綁定的主要方式。
- 具有區塊作用域(block scope),範圍更安全且易於控制。
區塊作用域在第三章綁定和範圍中詳細解釋。
2.2 var
- 舊版 JavaScript 中的綁定聲明方式,現在已不推薦使用。
- 不受區塊作用域限制,容易導致不可預期的行為,詳細差異會在第三章綁定和範圍提及。
2.3 const
- 用於創建常量綁定,值在生命週期內不能重新賦值。
- 適合用於不會改變的數值或參考,能提高程式的可讀性和可靠性。
const greeting = "Hello";
console.log(greeting); // → Hello
greeting = "Bye"; // 語法錯誤,因為常量無法重新賦值
const無法重新賦值,但物件或陣列的內容仍然可以被改變:javascriptconst person = { name: "John" }; person.name = "Jane"; // 合法,因為物件內容可以修改 console.log(person.name); // → Jane person = { name: "Mike" }; // 語法錯誤,因為無法重新賦值
3. 初始化
- 如果綁定在定義時沒有賦值,則其值為
undefined。javascriptlet emptyBinding; console.log(emptyBinding); // → undefined - 可以在一條語句中定義多個綁定,但為了程式的可讀性,建議每行定義一個綁定。
javascript
let one = 1, two = 2; console.log(one + two); // → 3
4. 綁定名稱
4.1 有效名稱
- 必須以字母、
$或_開頭,不能以數字開頭。 - 名稱可以包含數字,但不得包含特殊字符(如
@、#等)。
let catch22 = "valid"; // 合法
let 22catch = "invalid"; // 非法,會產生語法錯誤
let $name = "valid"; // 合法
let _name = "valid"; // 合法
4.2 關鍵字(Keyword)
JavaScript 中有一些具有特殊意義的詞,稱為關鍵字,不能用作綁定名稱。
let let = 5; // 語法錯誤,因為 "let" 是關鍵字
4.3 保留字(Reserved Word)
某些詞雖然目前未被使用,但被保留為未來版本的關鍵字,也不能用作綁定名稱。
4.4 關鍵字與保留字列表
以下是 JavaScript 的關鍵字和保留字,這些詞無法用作綁定名稱:
break, case, catch, class, const, continue, debugger, default,
delete, do, else, enum, export, extends, false, finally, for,
function, if, implements, import, interface, in, instanceof, let,
new, package, private, protected, public, return, static, super,
switch, this, throw, true, try, typeof, var, void, while, with, yield
函式(Function)
函式(Function) 是一段能重複運行的程式碼片段,可以透過呼叫來執行。呼叫函式需要在函式名稱後面加上括號,而括號中的內容稱為參數(argument)。
prompt("Enter passcode");
1. 定義函式
在 JavaScript 中,可以使用 function 關鍵字來定義函式。以下是基本語法:
範例:定義與呼叫函式
function greet(name) {
return "Hello, " + name + "!";
}
console.log(greet("Alice")); // → Hello, Alice!
console.log(greet("Bob")); // → Hello, Bob!
2. 回傳值(Return Value)
有些函式執行後會生成一個值,這個值稱為回傳值,可以使用 return 關鍵字回傳到呼叫函式的位置。
2.1 使用內建函式的回傳值
Math.max 是一個內建函式,用於返回多個數字中的最大值。
console.log(Math.max(2, 4)); // → 4
回傳值也可以作為更大表達式的一部分來運算:
console.log(Math.min(2, 4) + 100); // → 102
2.2 自定義函式的回傳值
以下是自定義函式返回值的範例:
function add(a, b) {
return a + b;
}
console.log(add(5, 3)); // → 8
console.log(add(10, 20)); // → 30
函式會在第三章重點琢磨:【JavaScript 學習筆記 03】Chapter 3 Functions
控制流程(Control flow)
正常情況下,程式中的語句會按照由上至下的順序依次執行,除非加入控制流程。控制流程是決定程式執行順序和邏輯的結構,讓程式能根據條件選擇性地執行某些程式碼,或重複執行特定的程式碼段。
1. 有條件執行
當程式需要根據不同條件執行不同動作時,可以使用 if-else 語句或 switch 語句。
1.1 if-else
if-else 是最常用的條件語句,適合處理範圍檢查或複雜條件。
let age = 18;
if (age >= 18) {
console.log("You are an adult.");
} else {
console.log("You are a minor.");
}
// → You are an adult.
1.2 switch
switch 結構清晰,適合多條件分派。當條件值是固定的(如字串或數字)時,switch 會更加直觀。
let fruit = "apple";
switch (fruit) {
case "apple":
console.log("You chose an apple.");
break;
case "banana":
console.log("You chose a banana.");
break;
default:
console.log("Unknown fruit.");
break;
}
// → You chose an apple.
switch會檢查表達式,並從匹配的case開始執行。- 如果一個
case區塊中沒有break,程式會繼續執行下一個case的程式碼。 default是可選的,當沒有匹配的值時執行。
小結
if-else:適合處理複雜條件(例如:範圍檢查)。switch:適合處理固定條件值(例如:字串或數字)。
2. 循環執行(Loops)
2.1 While Loops
while 迴圈會在每次執行前檢查條件,若條件為 true 則執行,否則結束迴圈。
let number = 0;
while (number <= 12) {
console.log(number);
number = number + 2;
}
// → 0
// → 2
// … 直到 number = 14,14 <= 12,跳出迴圈
- 適用場景:當條件未知,或需要根據某些狀態來決定是否繼續執行時。
2.2 Do Loops
do-while 迴圈至少會執行一次,然後再檢查條件是否為 true。
let yourName;
do {
yourName = prompt("Who are you?");
} while (!yourName);
console.log("Hello " + yourName);
- 適用場景:當需要確保程式碼至少執行一次時。
2.3 For Loops
for 迴圈是一種結構清晰的迴圈,適合用於已知次數的情況。它將「初始化」、「條件檢查」和「更新狀態」集中在一起。
for (let num = 0; num <= 12; num = num + 2) {
console.log(num);
}
// → 0
// → 2
// …直到 num = 14,跳出迴圈
- 初始化:
let num = 0 - 條件檢查:
num <= 12 - 更新計數器:
num = num + 2
- 適用場景:當需要執行固定次數的迴圈時。
2.4 打破循環
條件檢查得出 false 並不是唯一完成迴圈的方法,若在中間想提早結束迴圈,可以使用 break。
以下程式碼會找出第一個大於或等於 20 且能被 7 整除的數字,然後跳出迴圈:
for (let current = 20; ; current = current + 1) {
if (current % 7 == 0) {
console.log(current);
break;
}
}
// → 21
小結
while:適合條件未知的情況,根據條件執行迴圈。do-while:至少執行一次,然後根據條件決定是否繼續。for:適合已知次數的迴圈,結構清晰。break:用於提早結束迴圈。
程式風格(Coding Style)
1. 分號
在 JavaScript 中,分號用於結束語句。雖然 JavaScript 的自動分號插入(Automatic Semicolon Insertion, ASI)機制可以在某些情況下省略分號,但這可能導致代碼被錯誤解讀。因此建議在每個語句結尾都加上分號,這是更安全的做法。
延伸閱讀:JS 加不加分號差在哪?
2. 縮排
縮排是提升程式碼可讀性的重要方式。雖然程式執行時不會對縮排有要求,但對於人類來說,良好的縮排習慣可以讓程式碼結構更加清晰。
常見縮排規範
- 兩個空格:適合程式碼較長或嵌套較深的情況,常見於 Google 的 JavaScript 風格指南。
- 四個空格:適合程式碼較短或需要更明顯的層次感,常見於一些大型專案。
// 使用兩個空格
function sayHello() {
console.log("Hello, world!");
}
// 使用四個空格
function sayHello() {
console.log("Hello, world!");
}
無論選擇哪種縮排方式,保持一致性是最重要的。
3. 命名規則
變數和函式的命名應該具有描述性,並遵循統一的命名規則。以下是幾種常見的命名風格:
3.1 命名風格
- Snake Case:
fuzzy_little_turtle
常見於某些後端語言(例如:Python)。 - Pascal Case:
FuzzyLittleTurtle
通常用於類名或建構函式名稱,例如:javascriptclass FuzzyLittleTurtle { constructor() { this.name = "Turtle"; } } - Lower Camel-Case:
fuzzyLittleTurtle
JavaScript 中最常見的命名方式,適用於變數和函式名稱,例如:javascriptlet fuzzyLittleTurtle = "Turtle"; function getTurtleName() { return fuzzyLittleTurtle; }
3.2 命名規則的建議
- 使用描述性名稱,例如:
totalAmount而非x。 - 避免縮寫,除非是廣為人知的縮寫(例如:
id表示identifier)。 - 在同一專案中保持命名風格的一致性。
4. 註解
註解的目的是補充程式碼的意圖,幫助讀者理解程式碼的功能與邏輯。良好的註解應該簡潔明確,避免過度冗長。
4.1 註解的類型
- 單行註解:使用
//,適合簡短的說明。javascriptlet accountBalance = calculateBalance(account); // 計算帳戶餘額 accountBalance.adjust(); // 調整餘額 - 多行註解:使用
/* */,適合較長的說明或模組級別的註解。javascript/* 這段程式碼用於處理帳戶餘額。 它會先計算餘額,然後進行調整, 最後將結果加入報告中。 */ const myNumber = 11213;
4.2 註解的最佳實踐
- 簡潔明確:註解應該直接說明程式碼的功能或邏輯,不要重複程式碼內容。
- 避免過度註解:過多的註解可能會使程式碼難以閱讀,應該讓程式碼本身具有自解性。
- 使用標籤:例如
TODO、FIXME、NOTE,幫助標記需要後續處理的部分。
範例:使用標籤註解
// TODO: 優化此函式的效能
function processLargeData(data) {
// FIXME: 當資料量過大時,可能會導致記憶體不足
return data.map(item => item * 2);
}
小結
- 分號:建議在每個語句結尾加上分號,避免潛在的語法錯誤。
- 縮排:選擇兩個或四個空格,並保持一致性。
- 命名規則:使用描述性名稱,並根據用途選擇合適的命名風格。
- 註解:簡潔明確,避免過度註解,並善用標籤來記錄待處理事項。
總結
我們探討了 JavaScript 的基本程式結構。從表達式、語句、綁定到函式及控制流程,逐步展示了如何構建有效的程式碼架構。同時也強調了良好的程式風格對於提升程式碼可讀性的重要性,並提供了一些實際建議。
關鍵要點
- 表達式是產生值的程式碼片段,語句是完整的指令
- 綁定用於儲存和更新程式中的數值或狀態
- 函式是可重複使用的程式碼片段,能接受參數並返回結果
- 控制流程決定了程式執行的順序與邏輯
- 良好的程式風格能提升程式碼的可讀性和可維護性
實踐建議
- 使用分號
;結束每條語句,以避免潛在的語法錯誤 - 保持一致的縮排風格,提升程式碼結構的清晰度
- 選擇具有描述性的命名方式,使程式碼更易於理解
- 適當使用註解來補充程式碼的意圖,幫助讀者理解
- 定期回顧和重構程式碼,以保持其可讀性和可維護性
以上內容是基於 2. Program Structure - Eloquent JavaScript 4th edition (2024) 所整理的精簡筆記。