🚀 JavaScript 基礎(第 03 週):每個開發者都應該了解的概念
「撰寫 JavaScript 程式碼是一回事,但了解幕後發生的事情才能讓你成為更好的開發者。」
當我剛開始學習 JavaScript 時,我知道如何宣告變數和撰寫函式。然而,我常常會問自己:
- 為什麼有三種宣告變數的方法?
- 到底什麼是提升(hoisting)?
- JavaScript 是如何執行我的程式碼的?
- 為什麼內層函式可以存取父函式的變數?
this關鍵字到底指向什麼?- 為什麼開發者一直在談論撰寫乾淨的程式碼?
這週,我專注於理解這些 JavaScript 核心概念,而不只是死記語法。
在這篇文章中,我會以初學者友善的方式搭配範例與實務解釋來說明每個概念。
📚 涵蓋主題
- 變數(
var、let、const) - 提升(Hoisting)
- 詞法作用域(Lexical Scope)
- 執行環境(Execution Context)
- 呼叫堆疊(Call Stack)
- 閉包(Closures)
-
this綁定 - DRY 原則
- KISS 原則
讓我們從頭開始。
📦 JavaScript 中的變數
什麼是變數?
變數是一個用來在記憶體中儲存資料的命名容器。
與其重複撰寫相同的值,我們可以將它儲存在變數中,並在需要時重複使用。
例如,
let name = "Sai";
console.log(name);
Enter fullscreen mode Exit fullscreen mode
輸出
Sai
Enter fullscreen mode Exit fullscreen mode
在這裡,
-
let→ 變數宣告關鍵字 -
name→ 變數名稱 -
"Sai"→ 儲存的值
為什麼需要變數?
想像撰寫以下程式碼:
console.log("Sai");
console.log("Sai");
console.log("Sai");
Enter fullscreen mode Exit fullscreen mode
如果值改變,就必須更新每一處。
使用變數後,
let name = "Sai";
console.log(name);
console.log(name);
console.log(name);
Enter fullscreen mode Exit fullscreen mode
現在只需修改一行,就能更新所有使用處。
變數可提升:
- 可讀性
- 可重用性
- 可維護性
變數的類型
JavaScript 提供了三種宣告變數的方式。
- var
- let
- const
雖然這三者都能建立變數,但它們的行為不同。
var
var 在 JavaScript 的第一個版本中就被引入。
特性:
- 函式作用域
- 可以重新宣告
- 可以重新指派
- 會被提升
範例
var city = "Hyderabad";
var city = "Bangalore";
console.log(city);
Enter fullscreen mode Exit fullscreen mode
輸出
Bangalore
Enter fullscreen mode Exit fullscreen mode
因為 var 允許重新宣告,它可能意外覆寫現有值。
let
let 在 ES6 中被引入。
特性
- 區塊作用域
- 無法重新宣告
- 可以重新指派
範例
let age = 20;
age = 21;
console.log(age);
Enter fullscreen mode Exit fullscreen mode
輸出
21
Enter fullscreen mode Exit fullscreen mode
const
當變數不應被重新指派時,請使用 const。
特性
- 區塊作用域
- 無法重新宣告
- 無法重新指派
const PI = 3.14;
console.log(PI);
Enter fullscreen mode Exit fullscreen mode
輸出
3.14
Enter fullscreen mode Exit fullscreen mode
📈 提升(Hoisting)
什麼是提升?
提升是 JavaScript 在執行程式碼前先處理宣告的行為。
這並不代表程式碼在實體上移動。相反地,在記憶體建立階段,JavaScript 會在執行開始前先準備變數與函式。
範例
console.log(language);
var language = "JavaScript";
Enter fullscreen mode Exit fullscreen mode
輸出
undefined
Enter fullscreen mode Exit fullscreen mode
在內部,JavaScript 會將它視為:
var language;
console.log(language);
language = "JavaScript";
Enter fullscreen mode Exit fullscreen mode
使用 let 和 const 宣告的變數也會被提升,但它們會留在暫時性死區(TDZ)中,直到被初始化。
🌍 詞法作用域
作用域決定變數可以在哪裡被存取。
詞法作用域指的是,內層函式可以存取外層函式中宣告的變數,這是由於它撰寫的位置所決定的。
範例
function outer(){
let message="Hello";
function inner(){
console.log(message);
}
inner();
}
outer();
Enter fullscreen mode Exit fullscreen mode
輸出
Hello
Enter fullscreen mode Exit fullscreen mode
JavaScript 會先在 inner() 內搜尋。如果找不到變數,它會繼續在外層函式中尋找。
這個搜尋過程稱為作用域鏈(Scope Chain)。
⚙️ 執行環境
在 JavaScript 執行任何程式碼之前,會先建立一個執行環境。
可以把它想像成 JavaScript 的工作區。
它會儲存:
- 變數
- 函式
- 作用域
this的值
每個執行環境都有兩個階段。
記憶體建立階段
在此階段,
- 變數會被配置記憶體。
-
var變數會被初始化為undefined。 - 函式宣告會被儲存。
執行階段
在此階段,
- 變數會取得值。
- 陳述式會逐一執行。
- 函式呼叫會建立新的執行環境。
📚 呼叫堆疊
呼叫堆疊會追蹤函式的執行。
它遵循後進先出(LIFO)原則。
範例
function first(){
second();
}
function second(){
console.log("Inside Second");
}
first();
Enter fullscreen mode Exit fullscreen mode
輸出
Inside Second
Enter fullscreen mode Exit fullscreen mode
執行流程
first()
↓
second()
↓
console.log()
↓
Return
↓
Return
Enter fullscreen mode Exit fullscreen mode
🔒 閉包
JavaScript 最強大的特性之一就是閉包。
當內層函式即使在外層函式執行完畢後,仍然記得外層函式的變數時,就會建立閉包。
範例
function counter(){
let count = 0;
return function(){
count++;
console.log(count);
}
}
const increment = counter();
increment();
increment();
increment();
Enter fullscreen mode Exit fullscreen mode
輸出
1
2
3
Enter fullscreen mode Exit fullscreen mode
閉包通常用於:
- 計數器
- 資料隱私
- 事件處理器
- 模組模式
🎯 理解 this
this 關鍵字指的是呼叫函式的物件。
它的值取決於函式如何被呼叫。
隱式綁定
const user = {
name:"Sai",
greet(){
console.log(this.name);
}
}
user.greet();
Enter fullscreen mode Exit fullscreen mode
輸出
Sai
Enter fullscreen mode Exit fullscreen mode
顯式綁定
JavaScript 提供了 call()、apply() 和 bind() 來明確決定 this 應該指向哪個物件。
function greet(){
console.log(this.name);
}
const user={
name:"Sai"
};
greet.call(user);
Enter fullscreen mode Exit fullscreen mode
輸出
Sai
Enter fullscreen mode Exit fullscreen mode
new 綁定
function Student(name){
this.name=name;
}
const s1=new Student("Sai");
console.log(s1.name);
Enter fullscreen mode Exit fullscreen mode
輸出
Sai
Enter fullscreen mode Exit fullscreen mode
箭頭函式
箭頭函式沒有自己的 this。
相反地,它們會從周圍的作用域繼承 this。
✨ DRY 原則
DRY 代表
Don't Repeat Yourself(不要重複自己)
與其重複撰寫程式碼,
console.log("Welcome Sai");
console.log("Welcome Rahul");
Enter fullscreen mode Exit fullscreen mode
不如撰寫
function greet(name){
console.log(`Welcome ${name}`);
}
greet("Sai");
greet("Rahul");
Enter fullscreen mode Exit fullscreen mode
優點
- 可重用程式碼
- 易於維護
- 減少重複
💡 KISS 原則
KISS 代表
Keep It Simple, Stupid(保持簡單)
簡單的程式碼比複雜的程式碼更容易理解。
與其撰寫
function isEven(num){
if(num%2===0){
return true;
}
else{
return false;
}
}
Enter fullscreen mode Exit fullscreen mode
不如撰寫
function isEven(num){
return num%2===0;
}
Enter fullscreen mode Exit fullscreen mode
簡單的程式碼:
- 易於除錯
- 易於維護
- 易於理解
🎯 重點摘要
完成這週的學習後,我了解到:
- 變數用來儲存資料。
- 提升發生在記憶體建立階段。
- 詞法作用域決定變數在哪裡可以被存取。
- 執行環境提供程式碼執行的環境。
- 呼叫堆疊管理函式的執行。
- 閉包會在函式結束後保留變數。
this的值取決於函式如何被呼叫。- 遵循 DRY 與 KISS 原則有助於撰寫乾淨且易維護的程式碼。
📝 結論
學習 JavaScript 不只是撰寫程式碼,更是了解語言在幕後如何運作。執行環境、作用域、閉包和 this 綁定等概念解釋了為什麼我們的程式碼會以這種方式運作。將這些基礎知識與 DRY 和 KISS 等乾淨程式碼原則結合,我們就能撰寫不僅正確,而且易讀、易維護且易擴展的程式碼。
0 Comments
Log in to join the conversation.No comments yet. Be the first to share your thoughts.