ecmascript5中引入的嚴格模式,通過讓javascript運作環境對一些開發過程中最常見和不易發現的錯誤做出和目前不同的處理,來讓開發者擁有一個”更好”的javascript語言。很長一段時間内,由于隻有firefox支援嚴格模式,我曾對嚴格模式表示懷疑。但到了今天,所有主流的浏覽器都在他們的最新版本中支援了嚴格模式(包括ie10,opera12和android4,ios5)是時候開始使用嚴格模式了。
在開始學習具體特性前,請記住<code>嚴格模式的一大目标是讓你能更快更友善的調試</code>。運作環境在發現問題時顯性的抛出錯誤比默不做聲的失敗或怪異行事(未開啟嚴格模式的javascript運作環境經常這樣)要好。嚴格模式會抛出更多錯誤,但這是好事,因為這些錯誤會喚起你注意并修複很多以前很難被發現的潛在問題。
首先,嚴格模式中去除了with語句,包含with語句的代碼在嚴格模式中會抛出異常。是以使用嚴格模式的第一步:確定你的代碼中沒有使用with。
其次,局部變量在指派前必須先進行申明。在啟用嚴格模式之前,為一個未申明的局部變量複制時會自動建立一個同名全局變量。這是javacript程式中最容易出現的錯誤之一, 在嚴格模式中嘗試這麼做時會有顯性的異常抛出。
嚴格模式中另一個重要的變化是函數中未被定義或為空( null or undefined)的this不在預設指向全局環境(global)。這會造成一些依賴函數中預設this行為的代碼執行出錯,例如:
this在被指派之前會一直保持為undefined,這意味着當一個構造函數在執行時,如果之前沒有明确的new關鍵詞,會抛出異常。
在上面的代碼中,person構造函數運作時因為之前沒有new,函數中的this會保留為undefined, 由于你不能為undefined設定屬性,上面的代碼會抛出錯誤。 在非strict模式環境中,沒有被複制的this會預設指向window全局變量,運作的結果将是意外的為window全局變量設定name屬性。
當編寫大量代碼時,對象屬性和函數參數很容易一不小心被設定成一個重複的名字。嚴格模式在這種情況下會顯性的抛出錯誤
以上的代碼在嚴格模式中都會被認為是文法錯誤而在執行前就讓你能得到提示。
雖然eval()語句最終沒有被移除,但在嚴格模式中仍然對它進行了一些改進。最大的改變是在eval()中執行的變量和函數申明不會直接在目前作用域中建立相應變量或函數,例如:
任何在eval()執行過程中建立的變量或者函數保留在eval()中。但你能明确的從eval()語句的傳回值來擷取eval()中的執行結果,例如:
ecmascript5中還引入為對象的特定屬性設為隻讀,或讓整個對象不可修改的能力。 但在非嚴格模式中,嘗試修改一個隻讀屬性隻會默不做聲的失敗。 在你和一些浏覽器原生api打交道過程中,你很可能遇到這種情況。嚴格模式會在這種情況下明确的抛出異常,提醒你修改這個屬性是不被允許的。
上面的例子中,name屬性被設為隻讀,非嚴格模式中執行對name屬性的修改不會引發報錯,但修改不會成功。但嚴格模式則會明确的抛出異常。
note: 強烈建議你在使用任何ecmascript屬性特性指定時開啟嚴格模式。
在現代浏覽器中開啟嚴格模式非常容易,隻需要在javascript代碼中出現以下指令即可
雖然看上去上面的代碼僅僅隻是未賦予某個變量的字元串,它實際上起到訓示javascript引擎切換到嚴格模式的作用(不支援嚴格模式的浏覽器會忽略以上代碼,不會對後續的執行産生任何影響)。雖然你能把這個指令作用到全局或某個函數中,但這裡還是要提醒,不要在全局環境下啟用嚴格模式。
雖然上面的代碼看起來不算一個大問題。但當你不負責維護頁面中引入的全部代碼時,這樣使用strict模式會讓你面臨由于第三方代碼沒有為嚴格模式做好準備而引發的問題。 是以,最好把開啟嚴格模式的指令作用于函數中,例如:
如果你想讓嚴格模式在不止一個函數中開啟,請使用立即執行函數表達式
我強烈建議你從現在開始就啟用javascript嚴格模式,它能幫你發現代碼中未曾注意到的錯誤。不要在全局環境中啟用,但你能盡量多的使用iife(立即執行函數表達式)來把嚴格模式作用到多個函數範圍内。一開始,你會遇到之前未曾碰到過的錯誤提示,這是正常的。當啟用嚴格模式後,請確定在支援的浏覽器中做了測試,以發現新的潛在問題。一定不要僅僅在代碼中添加一行”use strict”就假定餘下的代碼能正常工作。最後,請在嚴格模式下開始編寫更好的代碼。
參考:
<a href="http://www.nczonline.net/blog/2012/03/13/its-time-to-start-using-javascript-strict-mode/">http://www.nczonline.net/blog/2012/03/13/its-time-to-start-using-javascript-strict-mode/</a>
<a href="https://developer.mozilla.org/en-us/docs/web/javascript/reference/functions_and_function_scope/strict_mode">https://developer.mozilla.org/en-us/docs/web/javascript/reference/functions_and_function_scope/strict_mode</a>