JavaScript Strict Mode (嚴格模式)
Strict Mode(嚴格模式)是 ES5 引入的功能,透過在程式碼開頭加上 'use strict' 字串來啟用。嚴格模式會讓 JavaScript 引擎以更嚴格的規則執行程式碼,幫助你避免一些常見錯誤,寫出更安全的程式碼。
如何啟用嚴格模式
整個 script 啟用
在 script 或 JavaScript 檔案的最開頭加上 'use strict':
'use strict';
// 這個檔案中的所有程式碼都會以嚴格模式執行
var x = 10;
'use strict' 必須放在程式碼的最開頭,前面只能有註解或空白。如果放在其他程式碼後面就無效。單一函式啟用
也可以只在特定函式內啟用嚴格模式:
function strict() {
'use strict';
// 這個函式內以嚴格模式執行
}
function notStrict() {
// 這個函式不是嚴格模式
}
ES6 模組自動啟用
使用 ES6 模組 時,模組內的程式碼會自動以嚴格模式執行,不需要手動加上 'use strict'。
嚴格模式的限制
1. 變數必須宣告
在一般模式下,忘記用 var 宣告變數會自動建立全域變數,這是常見的錯誤來源。嚴格模式會直接拋出錯誤:
'use strict';
x = 10; // ReferenceError: x is not defined
// 正確做法
var x = 10;
2. 禁止刪除變數和函式
'use strict';
var x = 10;
delete x; // SyntaxError
function foo() {}
delete foo; // SyntaxError
3. 禁止重複的參數名稱
'use strict';
// SyntaxError: Duplicate parameter name not allowed
function sum(a, a) {
return a + a;
}
4. 禁止八進位字面值
'use strict';
var num = 010; // SyntaxError
// 如果需要八進位,使用 0o 前綴(ES6)
var num = 0o10; // 8
5. 禁止對只讀屬性賦值
'use strict';
var obj = {};
Object.defineProperty(obj, 'x', { value: 10, writable: false });
obj.x = 20; // TypeError: Cannot assign to read only property
// 對不可擴展的物件新增屬性也會報錯
Object.preventExtensions(obj);
obj.y = 20; // TypeError: Cannot add property y
6. 禁止刪除不可配置的屬性
'use strict';
delete Object.prototype; // TypeError
7. eval 有獨立作用域
在嚴格模式下,eval() 中宣告的變數不會洩漏到外部作用域:
'use strict';
eval('var x = 10;');
console.log(x); // ReferenceError: x is not defined
8. this 預設是 undefined
在一般模式下,函式中的 this 如果沒有指定會指向全域物件(瀏覽器中是 window)。嚴格模式下,this 會是 undefined:
'use strict';
function showThis() {
console.log(this);
}
showThis(); // undefined(一般模式會是 window)
9. 禁止使用保留字作為變數名
'use strict';
// 這些都會報錯
var implements = 1;
var interface = 1;
var let = 1;
var package = 1;
var private = 1;
var protected = 1;
var public = 1;
var static = 1;
var yield = 1;
10. 禁止 with 語句
'use strict';
// SyntaxError
with (obj) {
x = 10;
}
為什麼要使用嚴格模式?
- 提早發現錯誤:許多原本會被忽略的錯誤會立即拋出,更容易除錯
- 避免意外的全域變數:忘記 var 不再會自動建立全域變數
- 更安全:禁止了一些不安全的功能(如 with 語句)
- 為未來版本做準備:保留字不能作為變數名,避免與未來語法衝突
- 效能優化:某些情況下,JavaScript 引擎可以對嚴格模式程式碼做更好的優化
實際範例
範例一:防止意外的全域變數
// 一般模式 - typo 會建立全域變數
var userName = 'Mike';
userNmae = 'John'; // 打錯字,建立了新的全域變數
console.log(userName); // 還是 'Mike'
// 嚴格模式 - 會報錯
'use strict';
var userName = 'Mike';
userNmae = 'John'; // ReferenceError
範例二:this 的安全性
// 一般模式 - 可能意外修改全域物件
function setName(name) {
this.name = name;
}
setName('Mike'); // 意外在 window 上設定了 name
// 嚴格模式 - 會報錯
'use strict';
function setName(name) {
this.name = name;
}
setName('Mike'); // TypeError: Cannot set property 'name' of undefined
相容性
嚴格模式被所有現代瀏覽器支援。'use strict' 對於不支援的舊瀏覽器來說只是一個普通的字串,不會造成錯誤,所以可以安全地使用。
建議
現代 JavaScript 開發中,建議總是使用嚴格模式。如果你使用 ES6 模組或現代打包工具(如 Webpack、Rollup),通常會自動套用嚴格模式。即便如此,在撰寫傳統 script 時,手動加上 'use strict' 仍是好習慣。