Just Suffering?
JS 是誰? 為什麼大家都 .js 了
Just Suffering? Who Is JS, and Why Does Everything End in .js?
JavaScript 是誰
讓網頁動起來的小腳本
JavaScript 是一種程式語言,簡稱 JS (廢話)。
【Game】自己寫一次看看
console.log('Hello World');
簡單粗暴地說,一個網頁通常會有 HTML 作為骨架 + CSS 畫漂漂亮亮的皮 + JS 讓他「動起來」。早期的 JS 主要就是負責讓瀏覽器「知道什麼時候該做什麼事」的腳本語言。
在這個情境下,你可以把瀏覽器理解成 JS 的其中一種 Runtime (執行環境)。而這個 Runtime 通常會包含:JS Engine、各種 Web APIs、Event Loop、Task Queues 等等。
其中 JS Engine 會負責解析 JS 原始碼、編譯與執行、記憶體管理,以及 Garbage Collection。可是 JS Engine 本身不懂 DOM、也不會自己發 request;這些能力要靠 Runtime 提供的 API 才做得到,例如 document.querySelector、fetch、localStorage 等等。
從瀏覽器母語發展而來的龐大生態系
Node.js (Node) 也是一種常見的 Runtime。他讓 JS 脫離瀏覽器,能在電腦其他環境上跑。而這個 Runtime 不會提供 DOM API,但會提供像 fs (檔案系統)或 process 這類偏系統層的 API。
🌰 以下是幾個常見的 JS Runtime 🌰
| Runtime | Node.js (Node) | Bun | Deno | Google Chrome | Microsoft Edge | Apple Safari | Mozilla Firefox |
|---|---|---|---|---|---|---|---|
| Type | Non Browser | Non Browser | Non Browser | Browser | Browser | Browser | Browser |
| Rendering Engine | N/A | N/A | N/A | Blink | Blink | WebKit | Gecko |
| JS Engine | V8 | JavaScriptCore (JSC) | V8 | V8 | V8 | JavaScriptCore (JSC) | SpiderMonkey |
這裡可以看到,只有「瀏覽器」這種 Runtime 會有 Rendering Engine,因為它得負責把 DOM/CSSOM 最後畫到螢幕上。 另外,在使用 Chrome/Edge/Perplexity 時可能會有點熟悉感,這不是錯覺,因為他們都來自開源瀏覽器專案 Chromium (內含 V8 和 Blink)。 再補充一點,即使是同一個瀏覽器,也可能因為作業系統不同,而導致引擎不同。最典型的例子是 Apple 的規範要求在 iOS 上「瀏覽網頁」類型的 App 必須使用 WebKit。所以在 iOS 上裝的 Chrome/Edge,本質上也只能是「WebKit 外皮」,行為和效能特性很多時候會更接近 Safari,而不是桌面版的 Chrome。(歐盟地區 2024 年後因為 DMA 法規開放了第三方引擎,這是例外中的例外)
【Game】因為 Runtime 不同而有所差異的結果
在瀏覽器跟非瀏覽器 Runtime 輸入指令
document.querySelector("div")(非瀏覽器 Runtime 會噴錯)import fs from 'fs';(瀏覽器 Runtime 會噴錯)[1,2,3].map(x => x * 2)(純 JS 兩邊都能跑)
對 JS 稍稍了解之後,就可以開始探索 JavaScript 的多重宇宙了:D
怎麼都 .js 了?
JavaScript 的多重宇宙
除了 Runtime 以外,用 JS 開發時每次都要手寫 document.getElementById 或其他實作太累了,於是各種「工具」誕生了。通常為了致敬「母語」,很多 JS 工具常以 .js 結尾。
🌰 以下是常見的 JS 工具 🌰
| 工具類型 | 工具名稱 |
|---|---|
| Runtime | Node.js Bun Deno |
| 前端框架 UI Library | Vue.js React Angular |
| 建置工具 (Build Tool) | Vite Webpack |
| Meta (全端框架) | Next.js (React 生態) Nuxt.js (Vue 生態) NestJS (後端架構) |
| 其他 | Three.js (3D 繪圖) Chart.js (圖表) Express.js (後端伺服器) |
特別說一下 Vite,它不是框架而是前端的「翻譯官兼打包機」,把人寫的程式碼變成瀏覽器能理解、能高效執行的形式,而且快爆。
Just Suffering?
過於貼心的 Type Coercion
縱使 JS 家族龐大,版圖遍布各種終端應用,但神通廣大的他還是有著一個現代語言難以置信的痛點。
1 == '1' // true
「蛤?」沒錯,結果毫無疑問是 true。
這不是 bug,而是 JS 的 Type Coercion,當使用 == 時,JS 會嘗試把兩邊轉成「看起來可以比較」的型別,再進行判斷。
所以結果就變成:
1 == Number('1') // true
其他呱張的案例還有:
0 == false // true
'' == false // true
null == undefined // true
[] == false // true
[] == ![] // true (瘋了,都瘋了)
// 空陣列被轉成 0
// ![] 會被轉成 false 再轉成 0
這也是為什麼 JS 社群裡流傳一句名言:
Never use
==, always use===. [name=Just Suffering Engineer] [color=orange]
前面用的 == (loose equality) 會在一定程度上忽略型別問題,而 === (strict equality) 就彌補了這點,它會同時比較型別是否一樣、值是否一樣。
1 === '1' // false
TypeScript 又是誰啦?
解決型別之痛
JavaScript 的彈性雖然方便快速開發,但由於太彈性了,導致常常會出現一些詭異的現象。
比如說,你寫 1 + "1" JS 會自作聰明算出 "11" (string) 而不是報錯。
你說這是 bug 嗎? JS 表示這是他的 feature :D
TypeScript (TS) 從名字就能看出他主打 JS 弱爆的 Type。核心特性是靜態型別系統,能在編譯階段就檢查程式碼錯誤,而不是等到執行時才開炸。
舉幾個簡單的例子 🌰
- 變數型別不一致
- JavaScript
let value = "hello";
value = 123;
console.log(value); // 123 - TypeScript
let value: string = "hello";
value = 123; // ❌ Error: Type 'number' is not assignable to type 'string'
- JavaScript
- 物件屬性不存在
- JavaScript
const user = { name: "Chestnut" };
console.log(user.age); // undefined - TypeScript
const user = { name: "Chestnut" };
console.log(user.age); // ❌ Error: Property 'age' does not exist on type '{ name: string; }'
- JavaScript
跟著 AI 浪潮起飛
TypeScript 解決的不只是 JavaScript 的痛點,他同時也成為了現代開發者的主流語言之一,並且在 GitHub 上的新專案數量在 2025 年八月超越了 Python。
原因是 TypeScript 除了靜態型別檢查,還可以與現有 JS 生態無縫整合,等於也有了大量開發工具支援。
並且 TypeScript 的「型別定義 (Types)」就是最精準的 prompt,他基本上也是 AI Coding Agent 的首選語言。因為比起讓 AI 猜測 user 裡到底有沒有 name 屬性,明確的 interface User { name: string } 可以讓產出的 code 品質更穩定。
工程之外的 JavaScript
名詞解放戰
話說回來,為什麼正式場合或文件經常看到的是「ECMAScript」或「JS」而不是「JavaScript」呢? 這是因為有間叫 Oracle 的公司,此時此刻在美國還擁有 JavaScript 這個名詞的商標權,但他們並沒有推出過名為 JavaScript 的產品,只是繼承自曾經收購的 Sun Microsystems (開發 Java 的公司)。 商標權的問題直接導致了很多書名、研討會主題明明是 JavaScript 但卻不能直接用 JavaScript 這個字,必須改用「JS」或「ECMAScript」之類的字代替,避免被告反而賠大錢。 聽起來很靠北,對吧? 於是 Ryan Dahl (也是 Node.js 和 Deno 的開發者) 和其他社群成員發起了 #FreeJavaScript 請願,要求美國專利局撤銷 Oracle 的商標,理由包括 JavaScript 已經成為通用詞、多年來 Oracle 未實際使用等等,結果如何,就等等看吧:D