學前端或後端,繞不開 JavaScript。它不是只用來「讓按鈕會動」的語言,而是從網頁互動、伺服器到桌面與行動 App 都能派上用場。
可惜版本一多,名字又有 ES5、ES6、ES202x,常把人搞糊塗:到底最新是什麼?大家實務上又用哪個?這篇把時間線理清,先說清楚 ES5 與 ES6 的關鍵差別(像 let/const、箭頭函式、class、模組),再談日常開發要掌握的觀念:嚴格模式、作用域、非同步、模組化,最後補上好懂的命名規則與限制。希望本篇文章可以幫助到需要的您。
目錄
{tocify} $title={目錄}
JavaScript 版本怎麼看?(ES 系列時間線)
ES1(1997)、ES2(1998)、ES3(1999)
ES4 計畫擱置(轉向 Harmony)
ES5(2009)、ES5.1(2011):奠定相容性與「嚴格模式」等核心能力。
ES6 = ECMAScript 2015(2015):語法大躍進(class、module、let/const、arrow function、Promise、for...of、模板字面值、解構、Map/Set 等)。自 2015 年起規格改為「每年六月一版」(ES2016、ES2017…)。
之後每年都有版本:ES2016、ES2017…一直到 ECMAScript 2025(第 16 版)。官方規格由 Ecma International 發布,TC39 維護 HTML 版「活規格」。
最新版本:ECMAScript 2025(第 16 版,2025 年 6 月),官方 HTML 與 PDF 皆可查閱。
目前最常被大眾使用的版本是什麼?
嚴格說,現代瀏覽器與 Node.js 都在持續實做最新規格(逐步齊備),而開發者日常寫作大多是所謂的 「現代 JavaScript(ES2015+)」:以 ES6 引入的基礎語法(模組、class、let/const、箭頭函式、解構、模板字面值等)為主,搭配工具鏈(Babel、TypeScript、Vite/webpack)視目標環境需要進行轉譯(transpile)與 polyfill。
換句話說,最多人實際「在寫」的是 ES2015 之後的語法族群,而不是侷限在 ES5。MDN 也說明了規格為「活規格」且每年定版,生態系會跟進最新標準。
ES5 與 ES6(ES2015)到底差在哪?——實務對照表+範例
1. 變數宣告與作用域:var vs let / const
ES5:只有 var(函式作用域、易受 hoisting 與重複宣告影響)。
ES6:let(可重新賦值、區塊作用域)、const(不可重新賦值、區塊作用域)。
// ES5
for (var i = 0; i < 3; i++) { setTimeout(() => console.log(i), 0); } // 3 3 3
// ES6
for (let j = 0; j < 3; j++) { setTimeout(() => console.log(j), 0); } // 0 1 2
const API_BASE = '/v1'; // 不能重新賦值
2. 函式寫法與 this 綁定:傳統 vs 箭頭函式
ES5:一般函式的 this 依呼叫位置決定,常見 var self = this 或 bind。
ES6:箭頭函式不綁定自己的 this,繼承外層語境,語法更精簡。
// ES5
var obj = {
value: 42,
inc: function() {
var self = this;
setTimeout(function(){ console.log(self.value); }, 0);
}
};
// ES6
const obj2 = {
value: 42,
inc() {
setTimeout(() => console.log(this.value), 0);
}
};
3. 原型模式 vs 類別語法(class)
ES5:使用原型鍊模擬類別。
ES6:class 語法糖,閱讀性與繼承可讀性更好。
// ES5
function Person(name){ this.name = name; }
Person.prototype.hello = function(){ return 'Hi ' + this.name; };
// ES6
class Person {
constructor(name){ this.name = name; }
hello(){ return `Hi ${this.name}`; }
}
4. 模組系統:無標準 → ES Modules
ES5:瀏覽器沒有原生標準(多用 IIFE、Browserify),Node 以 CommonJS 為主。
ES6:原生 ES Modules:import / export,瀏覽器與 Node 新版皆支援。
// module math.js
export const add = (a, b) => a + b;
// another file
import { add } from './math.js';
console.log(add(1, 2));
5. 非同步處理:回呼地獄 → Promise(後續 async/await)
ES5:以 callback 為主,層級深、錯誤傳遞易混亂。
ES6:Promise 成為標準;ES2017 再引入 async/await 讓寫法更直覺。
// ES6 Promise
fetch('/api')
.then(res => res.json())
.then(data => console.log(data))
.catch(err => console.error(err));
6. 語法糖與常用能力
模板字面值(Template Literals)`Hello ${name}`
解構賦值(Destructuring)與參數預設值、剩餘/展開運算子(...)
新集合型別:Map / Set
迭代器與 for...of
小結:ES6(ES2015)把「大型應用需要的語法」一次補齊,閱讀性、維護性與模組化全面提升;而這些語法現在都已是「日常」的現代 JS 寫法。
最新版本:ECMAScript 2025 概觀
身分:ECMA-262 第 16 版,2025 年 6 月定版。
節奏:規格每年六月定版,平時以「活規格」持續修訂;各家引擎(V8、SpiderMonkey、JavaScriptCore)逐步實做。
實務意義:你不需要背最新細節,但要知道「工具鏈+目標環境」決定你能用到哪些語法/API;若你的瀏覽器支援矩陣較新,就可以直接使用更多「原生」能力,減少轉譯與 polyfill 成本。
實務上該怎麼選「目標版本」?
1. 瀏覽器專案:
以 ES2015+ 作為寫作基線,搭配 Babel/TypeScript 設定 targets(如 last 2 versions, not IE 11)。
2. Node.js 專案:
依你的最低 Node 版本設定。新 LTS 一般支援大多數 ES2020+ 特性;原生 ES Modules 也已成熟。
3. 套件庫(library):
常見做法是輸出多種格式(如 ESM 與 CJS)與不同語法等級(modern 與 legacy),交由使用者環境決定載入哪一份。
這麼做的核心邏輯:寫 ES2015+,針對舊環境再降階;新專案就讓「現代語法」成為日常。
撰寫 JavaScript 的基礎知識
1. 嚴格模式("use strict")
讓 JS 進入更嚴謹的語義:禁止未宣告變數成為隱性全域、對某些非法指派拋錯等;可在檔頭或函式層級啟用。
"use strict";
x = 1; // 在嚴格模式會拋錯(未宣告)
2. 型別與相等性
原始型別(string、number、boolean、null、undefined、symbol、bigint)與物件型別。
優先使用 嚴格等於 ===;== 會做類型轉換,容易踩坑。
3. 作用域、提升(Hoisting)與閉包(Closure)
var 的函式作用域與提升、let/const 的區塊作用域,配合閉包可形成封裝。
4. 模組化與相依管理
使用 import/export,避免全域汙染;瀏覽器與 Node 皆支援(搭配打包器更穩)。
5. 非同步模型
事件迴圈(Event Loop)驅動;以 Promise 為基礎,async/await 讓流程看起來像同步。
命名規則與限制:哪些是「規範硬性規則」,哪些是「團隊風格建議」?
A. 規範層面的限制
1. 識別字(變數/函式/類別名稱)規則
通常以字母、底線 _、或 $ 開頭,後續可含數字;不能以數字開頭。
不只 ASCII,許多 Unicode 碼位也允許(例如部分非英文字元),但為跨團隊可讀性,仍建議以 ASCII 為主。
2. 保留字
某些關鍵字無法當識別字(例如 enum 在所有模式保留;implements、interface、package、private、protected、public、static 在嚴格模式保留)。若用到會拋 SyntaxError。
3. 模組與嚴格模式
ES Modules 自動採用嚴格模式(不需手動 "use strict")。在函式具「非簡單參數」時於函式內寫 "use strict" 也會報錯。
B. 團隊常見命名慣例(非強制,但強烈建議)
變數、函式:camelCase(如 fetchUserList)
類別、建構子:PascalCase(如 UserService)
常數:UPPER_SNAKE_CASE(如 DEFAULT_TIMEOUT_MS)
檔名:前端多用 kebab-case.js;React 元件常以 PascalCase.jsx/tsx
私有欄位:原生私有欄位用 # 前綴(如 #cache),避免再用底線假私有。
模組匯出:預設匯出(default)用清楚名稱,具名匯出(named exports)避免過度「大雜燴」。
好/壞名字示例
// 👍 好可讀
const maxRetries = 3;
function fetchUserList(){ /* ... */ }
class OrderHistory { /* ... */ }
// 👎 不建議
const a = 3; // 意義不明
function doIt(){ /* ... */ } // 職責不清
class Handle { /* ... */ } // 名稱過泛
綜合範例:把 ES5 寫法全面升級到現代 JS
需求
呼叫 API 取得使用者列表
篩出啟用中的使用者,依建立時間由新到舊
以模組與類別封裝,可重用
ES5(概念示意)
// api.js(沒有標準模組,只能靠 IIFE 或打包器)
var API = (function(){
var base = '/v1';
function getUsers(callback, errback){
var xhr = new XMLHttpRequest();
xhr.open('GET', base + '/users');
xhr.onload = function(){ callback(JSON.parse(xhr.responseText)); };
xhr.onerror = errback;
xhr.send();
}
return { getUsers: getUsers };
}());
// 使用
API.getUsers(function(list){
var actives = list.filter(function(u){ return u.active; });
actives.sort(function(a,b){ return new Date(b.createdAt) - new Date(a.createdAt); });
console.log(actives);
}, function(e){ console.error(e); });
ES2015+(現代寫法)
// api.js (ES Module)
const BASE = '/v1';
export async function getUsers(){
const res = await fetch(`${BASE}/users`);
if (!res.ok) throw new Error(`HTTP ${res.status}`);
return res.json();
}
// user-service.js
export class UserService {
static sortByNewest(users){
return [...users].sort((a, b) => new Date(b.createdAt) - new Date(a.createdAt));
}
static filterActive(users){ return users.filter(u => u.active); }
}
// index.js
import { getUsers } from './api.js';
import { UserService } from './user-service.js';
try {
const list = await getUsers();
const result = UserService.sortByNewest(UserService.filterActive(list));
console.log(result);
} catch (err) {
console.error(err);
}
這段現代寫法示範了:模組 import/export、const/let、箭頭函式、展開運算子、async/await、class、模板字面值——都是 ES2015+ 的日常配備。
問題集
Q1:我要不要還在意 ES5?
A:除非你要支援極舊的環境(如 IE11),否則開發層面以 ES2015+ 為主,工具會幫你降階。
Q2:最新版(ES2025)我能直接用嗎?
A:視目標環境而定。先查目標平台的支援度;不足之處交給 Babel/polyfill。官方規格每年更新、引擎逐步實做。
Q3:命名可以用中文嗎?
A:規格允許多數 Unicode 識別字,但可讀性與工具相容性考量,團隊通常統一英文字母與 camelCase。
Q4:ES Modules 會自動嚴格模式嗎?
A:會;且嚴格模式在模組下是預設。
