# Day 61:JavaScript 物件導向;HTML 骨架元素 **Published by:** [雞蛋糕的前端修煉屋](https://paragraph.com/@gcake/) **Published on:** 2026-02-24 **URL:** https://paragraph.com/@gcake/day-61 ## Content 2/16 - 2/20 農曆年假休息,少量看台大 Vibe coding Web app 開發開放式課程 課程講義 YouTube 影片播放清單📅 2026-02-23 | 🏷 JavaScript · OOP · HTML · CSS一、JavaScript 不是「傳統 OOP」JavaScript 採用原型導向(prototype-based),而非 Java、C++ 那種類別導向(class-based)。ECMAScript 規格書明確指出:"ECMAScript objects are not fundamentally class-based such as those in C++, Smalltalk, or Java." tc39兩者的根本差異在於繼承機制:傳統 OOP 繼承的是「結構 + 行為」,JavaScript 的原型鏈則可以連「狀態」一起繼承。 developer.mozilla機制傳統 OOP(Java / C++)JavaScript狀態由誰攜帶實例(instance)物件本身方法由誰攜帶類別(class)物件本身繼承的是什麼結構 + 行為結構 + 行為 + 狀態繼承機制類別繼承[[Prototype]] 鏈二、OOP 七個核心術語(汽車工廠比喻)術語白話解釋汽車比喻類別(class)設計藍圖工廠設計圖紙實例(instance)照藍圖造出的實體真正生產的一台車狀態(state)物件目前持有的資料油量、顏色、時速行為(behavior)物件能做的事加速、剎車、開燈方法(method)行為的程式碼實作accelerate() 函式結構(structure)物件有哪些屬性名稱規格表欄位繼承(inheritance)子類別自動獲得父類別的一切電動車沿用汽車設計三、三種建立物件的方式工廠函式(Factory Function)// 直接 return 物件,呼叫時不需要 new const createCar = (brand, color) => ({ brand, color, drive() { return `${brand} 行駛中`; // 透過閉包存取參數,不需要 this }, }); const bmw = createCar('BMW', 'red'); 不需要 new,呼叫方式與普通函式相同方法各自獨立,每個實例自己持有一份(記憶體消耗較高)無 prototype 鏈,instanceof 無效閉包天然封裝狀態,不依賴 this,不會有 this 跑掉的問題 developer.mozilla建構子函式(Constructor Function)function Car(brand, color) { this.brand = brand; // 每個實例自己的狀態 this.color = color; } // 方法手動掛到 prototype,所有實例共用同一份 Car.prototype.drive = function () { return `${this.brand} 行駛中`; }; const bmw = new Car('BMW', 'red'); // 忘記 new → this 指向全域物件 忘記 new 是最常見的 bug,this 會默默指向 window方法共用 prototype,省記憶體,適合大量實例 developer.mozilla支援 instanceof 型別判斷實務建議:新專案改用 class,此寫法僅需看懂 legacy codeClass(ES6+)class Car { #mileage = 0; // ES2020 真正的私有欄位,prototype 模式無法複製 constructor(brand, color) { this.brand = brand; this.color = color; } // 自動掛到 Car.prototype,不需要手動設定 drive() { return `${this.brand} 行駛中`; } addMileage(km) { this.#mileage += km; } } const bmw = new Car('BMW', 'red'); 底層與建構子函式完全相同,方法自動掛到 prototype developer.mozilla支援 extends 繼承,語法簡潔直觀自動開啟嚴格模式(strict mode),這是與建構子函式的重要差異私有欄位 # 是 ES2020 真正新增的語言能力,並非語法糖✅ 「class 是語法糖」大部分正確,但 ES2020 私有欄位 # 是例外。四、this 的運作邏輯this 的核心任務是:讓共用的方法知道「現在是哪個實例在呼叫我」。 Car.prototype ┌──────────────┐ │ drive() │ ← 全部實例共用同一個 function └──────┬───────┘ │ 被誰呼叫? ┌──────┴───────┐ ▼ ▼ bmw.drive() benz.drive() this = bmw this = benz ← this 動態指向呼叫者 this 的指向取決於「怎麼呼叫」,不是「在哪裡定義」。const bmw = new Car('BMW'); bmw.drive(); // ✅ this = bmw const fn = bmw.drive; // 把方法「拆出來」 fn(); // ❌ class 嚴格模式下 this = undefined → TypeError this 值依呼叫方式對照呼叫方式執行環境this 結果bmw.drive()任何模式bmw(呼叫的物件)fn() 普通呼叫非嚴格模式window(自動替換)fn() 普通呼叫嚴格模式 / classundefined(不替換)設計理念:寧可立刻看到 TypeError,也不要讓 this 默默污染 window。 developer.mozilla五、TypeScript 的防護網TypeScript 的核心價值:把執行期才會爆的錯誤,提前到編譯期攔截。this 型別標註class Car { brand = 'BMW'; drive(this: Car) { // 標註 this 必須是 Car 實例 return `${this.brand} 行駛中`; } } const fn = new Car().drive; fn(); // ❌ 編譯期直接報錯,不用等執行 其他常見防護// 傳錯型別 function setSpeed(speed: number) {} setSpeed('fast'); // ❌ 編譯期報錯 // 存取不存在的屬性 const car = { brand: 'BMW' }; car.color; // ❌ Property 'color' does not exist // class 屬性沒初始化 class Car { brand: string; // ❌ 沒有 initializer 也沒在 constructor 賦值 } 建議開啟 tsconfig.json:{ "compilerOptions": { "strict": true // 包含 noImplicitThis、strictNullChecks 等 } } 六、工廠函式的設計選擇用 const + 箭頭函式宣告的理由防止意外覆寫:const 確保函式參考不被覆蓋,function 宣告式則沒有這個保護。 stackoverflowconst createCar = (brand) => ({ brand }); createCar = () => {}; // ❌ TypeError 立刻報錯 沒有自己的 this:箭頭函式從語法層面斷掉 this,與工廠函式「不依賴 this」的設計一致。 ⚠ TDZ 限制:const 沒有 Hoisting,宣告前呼叫會拋出 ReferenceError。解法:把工廠函式的定義放在呼叫之前。三種宣告方式對照 const + 箭頭函式const + function 表達式function 宣告式防止意外覆寫✅✅❌定義前可呼叫(Hoisting)❌ TDZ 報錯❌ TDZ 報錯✅有自己的 this❌(工廠函式不需要)✅✅Airbnb 風格推薦✅可接受可接受七、三種模式選擇決策流程需要繼承(extends)嗎? ├── 是 → class └── 否 ↓ 會產生大量實例(百個以上)嗎? ├── 是 → class(方法共用 prototype 省記憶體) └── 否 ↓ 需要封裝私有狀態、或方便測試注入? ├── 是 → 工廠函式 └── 否 → 都可以,選團隊熟悉的 工廠函式最適合的情境// 依賴注入:db 可從外部傳入假資料,方便 TDD const createUserService = (db) => ({ async getUser(id) { return db.find(id); }, }); const fakeDb = { find: () => ({ name: 'Alice' }) }; const service = createUserService(fakeDb); 適合:需要閉包封裝私有狀態、重視測試性、Vue3 Composition API / React Hooks 等函式組合風格。 stackoverflow三種模式完整對照 工廠函式建構子函式Class需要 new❌✅✅方法共用 prototype❌ 各自一份✅✅支援 instanceof❌✅✅支援 extends❌手動且複雜✅私有欄位 #❌(用閉包代替)❌✅依賴注入友善✅❌較麻煩實務推薦✅ 現代主流❌ 僅維護舊碼✅ 繼承 / 大量實例八、HTML 骨架解析Emmet 產生的 Boilerplate
,