本文 AI 產出,尚未審核

JavaScript 課程 – 變數與資料型別

主題:嚴格模式('use strict'


簡介

在 JavaScript 的開發歷程中,嚴格模式(Strict Mode) 是一項重要的語法升級,它能讓程式在執行前即發現許多隱藏的錯誤與不安全的行為。對於剛踏入前端開發的初學者,以及想要提升程式碼品質的中級開發者而言,了解並善用嚴格模式是寫出可維護、可靠程式的第一步。

嚴格模式的核心目標是 「把不安全或不明確的語法變成錯誤」,從而迫使開發者以更嚴謹的方式撰寫程式。它不僅可以防止意外的全域變數、避免 this 被自動指向全域物件,還能阻止某些已被棄用的語法。透過本文的說明與範例,你將能快速掌握如何在不同情境下啟用嚴格模式,並了解它在實務專案中的最佳使用方式。


核心概念

1. 什麼是嚴格模式?

嚴格模式是一種 ECMAScript 5(ES5)之後引入的執行環境,透過在程式檔案或函式最前方加上字串 'use strict' 來啟用。啟用後,JavaScript 會在解析階段對以下行為拋出 SyntaxErrorReferenceError,而不是悄悄容忍或自行修正。

注意:嚴格模式是 可選 的,若未明確宣告,程式仍會在「非嚴格」模式下執行。

2. 啟用方式

範圍 語法範例 說明
全域 javascript\n'use strict';\n// 之後的全部程式皆為嚴格模式\n 直接在檔案最上方加入,整個檔案皆受限制。
函式 javascript\nfunction foo(){\n 'use strict';\n // 只在 foo 內部生效\n}\n 僅在該函式內部啟用,不影響外部程式。
模組 ES6 模組(import/export)自動為嚴格模式。 不需要額外宣告,所有模組均為嚴格。

小技巧:在大型專案中,建議以 全域嚴格模式 為主,搭配 ES6 模組,可確保每個檔案都受到保護。

3. 嚴格模式的主要限制

限制項目 非嚴格行為 嚴格模式結果 為什麼要限制
隱式全域變數 x = 10;(未宣告)會自動成為全域變數 ReferenceError: x is not defined 防止意外污染全域命名空間
this 之預設值 在函式直接呼叫時 this === window(瀏覽器) this === undefined(在嚴格模式) 避免在非物件方法中誤用 this
重複的參數名稱 function foo(a, a) {} 允許(舊版) SyntaxError 明確參數意圖,防止混淆
eval 的作用域 eval 可在呼叫者作用域新增變數 eval 僅在自己的作用域內部運作 防止 eval 改寫外部變數
刪除不可刪除的屬性 delete Object.prototype 失敗卻不拋錯 SyntaxError 保護內建屬性不被破壞
八進位字面值 var n = 010;(被解讀為八進位) SyntaxError 消除語法歧義
with 陳述式 with (obj) {} 可改變作用域 SyntaxError with 會導致作用域難以追蹤
保留字 implements, interface… 在舊版可作為變數名 SyntaxError 為未來擴充保留關鍵字

程式碼範例

以下示範 5 個常見且實用的範例,說明嚴格模式對程式行為的影響與最佳寫法。

範例 1:防止隱式全域變數

// 非嚴格模式(會產生隱式全域變數)
function nonStrict() {
  x = 100;            // ← 沒有宣告的變數,會自動掛在全域
}
nonStrict();
console.log(x);       // 100

// 嚴格模式(會拋出錯誤)
'use strict';
function strictMode() {
  // y = 200;          // ← 解除註解會得到 ReferenceError
  let y = 200;        // 正確寫法:使用 let/const/var 宣告
}
strictMode();
// console.log(y);   // ReferenceError: y is not defined

重點:在嚴格模式下,所有變數必須先宣告letconstvar),才能使用。


範例 2:this 的預設值

function showThis() {
  console.log(this);
}

// 非嚴格模式:直接呼叫時 this 會指向全域物件 (window)
showThis(); // [object Window]

// 嚴格模式:直接呼叫時 this 為 undefined
'use strict';
function showThisStrict() {
  console.log(this);
}
showThisStrict(); // undefined

// 若以物件方法呼叫,兩者皆指向該物件
const obj = {
  name: 'Alice',
  greet: function() {
    console.log(this.name);
  }
};
obj.greet(); // Alice

技巧:在寫函式庫或類別時,使用嚴格模式可以避免 this 被意外指向全域,減少 bug。


範例 3:禁止 with 與八進位字面值

'use strict';

// with (Math) {          // SyntaxError: Strict mode code may not include a with statement
//   console.log(sin(0)); // 會在非嚴格模式下正常執行
// }

let octal = 0o10; // 正確寫法:使用 0o 前綴
console.log(octal); // 8

// let oldOctal = 010; // SyntaxError: Octal literals are not allowed in strict mode

說明with 會改變作用域解析,容易產生不可預期的行為;八進位字面值的舊寫法 (010) 已被棄用,使用 0o 前綴才是標準寫法。


範例 4:eval 的作用域限制

'use strict';

function testEval() {
  eval('var a = 5;');   // a 只在 eval 本身的作用域內
  // console.log(a);   // ReferenceError: a is not defined
}
testEval();

為什麼重要:在非嚴格模式下,eval 可以在呼叫者作用域中新增變數,容易造成變數衝突與安全問題。嚴格模式將 eval 的作用域限制在自己的範圍,提升程式的可預測性。


範例 5:ES6 模組自動嚴格模式

// file: math.js(ES6 模組)
export function add(a, b) {
  // 這裡自動為嚴格模式
  return a + b;
}

// file: main.js
import { add } from './math.js';
console.log(add(3, 4)); // 7

結論:只要使用 import / export,即使沒有寫 'use strict',模組內部也會自動套用嚴格模式,讓開發者更安心。


常見陷阱與最佳實踐

陷阱 可能的錯誤 解決方式
忘記在函式開頭加 'use strict' 程式仍在非嚴格模式,隱式全域變數不易發現 統一在檔案最上方加入 'use strict',或使用 ES6 模組。
在非模組環境中混用 scriptmodule 同一檔案可能同時執行非嚴格與嚴格程式碼,導致行為不一致 type="module" 加到 <script> 標籤,確保整個檔案走嚴格模式。
使用 var 宣告變數,卻期望塊級作用域 var 仍會提升(hoisting),在嚴格模式下仍會產生意外 改用 let / const,確保變數僅在區塊內有效。
在嚴格模式下使用 arguments.callee arguments.callee 被禁止,拋出 TypeError 若需要遞迴,直接使用函式名稱或 箭頭函式
刪除不可刪除的屬性 delete Object.prototype 會產生 SyntaxError 避免刪除內建屬性,若真的需要,使用 Object.defineProperty 重新定義。

最佳實踐

  1. 全域啟用嚴格模式:在每個 JavaScript 檔案的最上方放置 'use strict';,或直接使用 ES6 模組。
  2. 統一使用 let / const:減少變數提升與意外覆寫。
  3. 避免使用 eval:若必須使用,確保內容可信且在嚴格模式下執行。
  4. 使用 Linter(如 ESLint):設定 strict: ["error", "global"],讓編譯時即捕捉未啟用嚴格模式的檔案。
  5. 在測試環境驗證:加入單元測試,確保在嚴格模式下的程式碼行為與預期一致。

實際應用場景

1. 前端框架與函式庫開發

在開發像 React、Vue、Angular 這類大型框架時,所有模組皆以 ES6 import/export 方式編寫,自動套用嚴格模式。框架開發者會利用嚴格模式保證:

  • 組件內部不會意外產生全域變數,避免不同組件之間的命名衝突。
  • this 的行為可預測,特別在 class component 中,this 必須指向實例。

2. Node.js 後端服務

Node.js 支援 ES6 模組(.mjs)或 CommonJS(require)。在 CommonJS 模組中,仍需手動加入 'use strict'

// file: db.js
'use strict';
const mysql = require('mysql2');
// 其餘程式碼...

此舉可防止在伺服器端意外創建全域變數,減少因變數污染導致的不可預期錯誤。

3. 舊版瀏覽器相容性

在需要支援 IE11 或更舊的環境時,仍可使用嚴格模式(IE9+ 已支援)。開發者可以在 Babel 轉譯過程中自動加入 'use strict',確保所有產出的 ES5 代碼皆受保護。

4. 安全性敏感的程式(如金流、認證)

在處理 金流、使用者認證 等安全性敏感的功能時,嚴格模式能降低因 eval、全域變數或 with 所導致的攻擊面。配合 CSP(Content Security Policy)一起使用,能大幅提升前端的安全防護。


總結

  • 嚴格模式 是 JavaScript 中提升程式碼品質、減少錯誤與安全漏洞的關鍵工具。
  • 只要在檔案最上方加上 'use strict';,或使用 ES6 模組,即可自動享有嚴格模式的保護。
  • let / const、模組化、ESLint 等現代開發實踐結合,能讓程式更易維護、錯誤更早被捕獲。
  • 初學者在寫練習題或小型專案時,務必養成 「每個檔案都使用嚴格模式」 的好習慣;中級開發者則應在團隊規範、CI 流程中強制執行,確保整個代碼基礎都受保護。

透過本文的概念說明與實務範例,你現在已經能夠:

  1. 正確在全域或函式層級啟用嚴格模式。
  2. 立即辨識並修正因 隱式全域變數this 預設值with 等產生的常見錯誤。
  3. 在前端框架、Node.js 後端或安全性敏感的應用情境中,安全且一致地使用嚴格模式。

嚴格模式 當作寫 JavaScript 的基本安全網,未來你會發現它不只是「防呆」工具,更是提升程式碼可讀性、可維護性與安全性的 必備武器。祝你寫程式順利,寫出乾淨、可靠的 JavaScript!