Day 13:看 Strict Mode 如何施展「還我漂亮拳」(2)
嚴謹模式下你不能做的事 (續)
8. 不能對不可刪除的屬性 (undeletable properties) 使用 delete
運算子
delete
運算子一般模式下,
delete
會回傳false
,但語法本身仍可以被接受。嚴謹模式下會直接拋錯。
錯誤類型:
TypeError: Cannot delete property 'prototype' of function Object() { [native code] }
使用前:
使用後:
9. 不能使用 eval
或 arguments
作為變數名稱
eval
或 arguments
作為變數名稱eval
和arguments
是 JavaScript 的關鍵字,各自另有用途,拿來作變數名稱容易導致非預期的結果。
錯誤類型:
SyntaxError: Unexpected eval or arguments in strict mode
使用前:
使用後:
10. 不能使用未來的保留字做變數名稱 (cannot use future reserved keywords as variables)
有些字眼可能還不是當前 JavaScript 版本支援的關鍵字,但根據程式語言發展的經驗,有些字眼被預期很有機會在未來成為實際有作用的關鍵字。
例如
interface
、public
、private
、package
等,在其他程式語言都是很重要也很普遍的關鍵字。考慮到既有程式對未來 JavaScript 新版本的移植性 (portable),這些字眼就不適合用來作為變數名稱。
以下是 W3Schools 列出的未來保留字,有些在 ES6 等後續版本已經成真:
implements
interface
let
package
private
protected
public
static
yield
錯誤類型:
TypeError: Cannot assign to read only property 'articleTarget' of object '#<Object>'
使用前:
使用後:
11. 用 eval()
宣告的變數或函數,不能在該 Scope 被語法呼叫使用
eval()
宣告的變數或函數,不能在該 Scope 被語法呼叫使用W3Schools 的原文是:For security reasons, eval() is not allowed to create variables in the scope from which it was called.
但嚴格來說,並不是
eval()
宣告的時候拋錯,而是後續想使用的時候拋錯,而且拋出的錯誤類型是ReferenceError
。此外,如果是在
eval()
內自己宣告自己使用也沒有問題,後續想用語法去呼叫使用才會拋錯。所以這邊我的理解是:
在嚴謹模式下,
eval()
所執行的語法會自成一個暫時的 Scope,在裡面宣告的變數或函數都只屬於這個 Scope。所以後續用語法呼叫時,不認得該變數或函數,因而拋出
ReferenceError
類型的錯誤。
錯誤類型:
ReferenceError: x is not defined
使用前(用於變數):
使用後(用於變數):
嚴謹模式下,在 eval()
內自己宣告自己使用並沒有問題:
使用前(用於函數):
使用後(用於函數):
12. 不能使用 with
語法
with
語法完全禁止
with
語法。
錯誤類型:
SyntaxError: Strict mode code may not include a with statement
使用前:
使用後:
13. 全域執行環境內的函數,裡面的 this
代表的物件不一樣
this
代表的物件不一樣一般模式下,全域執行環境內的函數裡面的
this
,指的是 Global Object。嚴謹模式下,全域執行環境內的函數裡面的
this
,變成undefined
。
使用前:
使用後:
嚴謹模式下你還是能……
嚴謹模式下增加了很多規範,目的是讓程式更安全。
不過也不是盡善盡美,還是有遺珠。
1. 還是可以重複宣告變數
這是一個很基本的不良語法,不過嚴謹模式並沒有加以控管。
這部分會建議使用前面文章介紹過的 let
或 const
來取代 var
,就可以限制變數重複宣告。
總結
嚴謹模式的使用情境相信還有很多,無法在幾篇文章的篇幅內全數囊括。但希望透過這三篇文章的介紹,能對嚴謹模式有一定深度的了解。
當專案規模越來越大,嚴謹的開發模式和程式撰寫方式才能讓專案更容易被多人維護,使用嚴謹模式是個必然的趨勢。
事實上可以注意到,著名的 JavaScript 編譯器 Babel 在將新版 ECMAScript 轉譯成 ES5 時,在你還沒打任何程式碼之前,ES5 的那一欄已經預設好一行程式,就是 use strict
!
References
Last updated