FOUNDATIONS PHASE 2 · 19
JavaScript Deep:真正難的是 State、Reference、Time
JavaScript 初學最常見的錯,不是忘記某個 method,而是搞錯「這個值現在指向誰」「closure 還能看到什麼」「callback 什麼時候跑」。這一課集中練 execution trace。
Learning outcomes
- 能區分 primitive value 與 object reference。
- 能解釋 closure 保存 lexical bindings。
- 能預測 async callback 的執行順序。
- 能從 TypeError / stale state 往前找錯誤假設。
1. Reference Sharing
const a = {
score: 80
};
const b = a;
b.score = 95;
console.log(
a.score
);
// 95a/b 指向同一個 object,因此 mutation 對兩邊都可見。
2. Shallow Copy
const user = {
profile: {
city: "Tainan"
}
};
const copy = {
...user
};
copy.profile.city =
"Taipei";外層是新 object,但 nested profile reference 仍共享。
3. Closure
function makeCounter() {
let count = 0;
return () => {
count++;
return count;
};
}
const counter =
makeCounter();回傳 function 仍可存取建立時的 lexical binding。
4. Async Ordering
console.log("A");
Promise.resolve()
.then(
() => console.log("B")
);
console.log("C");
// A
// C
// BCallback 不是看到就同步執行。要分 current call stack 與之後排程工作。
5. Runtime Evidence
TypeError:
Cannot read properties of undefined
at renderCourse (...)Stack trace 告訴你 crash site;root cause 可能更早在 data shape、find() 回 undefined、async race。
Project checkpoint:Course Workspace State Trace
state:
courses = []
selectedId = null
status = "idle"
click Load
→ status = "loading"
response
→ courses = [...]
→ status = "success"
click card
→ selectedId = 42把每個 event 對 state transition 寫清楚,UI bug 會容易定位很多。
Debug evidence:Stale State
如果 async request A 比後送的 B 晚回來,A 可能覆蓋較新的 state。這不是「網路亂掉」,而是程式缺少 cancellation/version guard。
Knowledge check
- object assignment 為什麼可能共享 mutation?
- spread 為什麼不是 deep copy?
- closure 保存的是值的快照嗎?
- 預測 A/C/B 並說明原因。