嚴格模式(Strict Mode)是ECMAScript5新增的功能。 ECMAScript5雖然可以向後相容ECMAScript3,但如果使用嚴格模式,哪些ECMAScript5「不在建議使用」的ECMAScript3語法功能將會被全部進制,如果出現就會拋出一行。引入Strict Mode目的是允許開發人員能夠選擇「更好」的Javascript版本,這個版本能以不同的方式處理那些普遍而又臭名昭著的錯誤。目前所有的主流瀏覽器的最新版本——包括IE10與Opera12——都支援嚴格模式。關於嚴格模式的大多數資訊都可以在《ES5規範》[PDF]的第223頁找到。
如何啟用嚴格模式
可以在全域範圍內使用嚴格模式,也可以在一個函數範圍內使用嚴格模式。如果要再全域範圍內啟用嚴格模式,只需要在程式的第一行使用程式碼即可:
程式碼如下:
function imStrict(){
}
啟用嚴格模式的語句只是一段普通的字串“use strict”,沒有任何新語法。這意味著不會對就舊式瀏覽器造成任何負面影響,因此可以大膽使用。
在函數內部啟用嚴格模式的一個實際應用是,把整個Javascript類別庫定義在嚴格模式的函數內部,這樣就可以不影響外部的程式碼:
複製程式碼
程式碼如下:
(function(){
"use strict"; })();
嚴格模式帶來了什麼?
在開始介紹特殊特性之前,你需要記住,嚴格模式的目標之一是允許更快地調試錯誤。幫助開發者調試的最佳途徑是當確定的問題發生時拋出相應的錯誤(throw errors when certain patterns occur),而不是悄無聲息地失敗或者表現出奇怪的行為(這正是如今不在嚴格模式下的Javascript做的)。嚴格模式下的程式碼拋出更多的錯誤信 息,這是好事,因為它能幫助開發者很快注意到一些必須立即解決的問題。
去除with語句(Eliminates with)
首先,嚴格模式去除了with語句。當with語句出現在嚴格模式中時,它會被認為是非法的Javascript語句並拋出語法錯誤。所以,使用嚴格模式的第一步就是確保你沒有在使用with。 程式碼如下:
// 在嚴格模式中會導致語法錯誤
// 在嚴格模式中會導致語法錯誤
with(location){
alert(href); }
複製程式碼
程式碼如下:
// 嚴格模式中拋出一個錯誤
// 嚴格模式中拋出一個錯誤 (function(){
someUndeclaredVar ="foo";
}());
複製程式碼
程式碼如下:
window.color ="red";
window.color ="red"; window.color ="red"; window.color ="red"; window.color ="red"; function sayColor(){ // 嚴格模式下,this不會指向window alert(this.color); } // 以下兩種情況,在嚴格模式下都拋出錯誤sayColor(); sayColor.call(null);
根本而言,this值必須賦值,否則將保留undefined值。這表示呼叫建構子時若漏掉了new關鍵字也會導致錯誤:
functionPerson(name){
this.name = name;
}
// 嚴格模式下導致錯誤
var me =Person("Nicholas");
在這段程式碼裡,呼叫Person建構子時缺少了new關鍵字,此時this值為undefined。由於你不能為undefined添加屬性,這段程式碼拋出了一個錯誤。在非嚴格模式下,this會強制轉換為全域對象,因此name屬性能夠被正確地賦值為全域變數。
拒絕重複(No duplicates)
當你做了大量的編碼的時候,你很容易在對像中定義了重複的屬性或者給函數定義了重複的參數名。嚴格模式下,這兩種情況都會導致錯誤的發生:
程式碼如下:
程式碼如下:
// 嚴格模式下錯誤- 重複參數
function doSomething(value1, value2, value1){
//code
}
// 嚴格模式下錯誤- 重複屬性
var object ={
foo:"bar", foo:"baz" };
複製代碼
代碼如下:
(function(){
eval( "var x = 10;");
// 非嚴格模式下,x為10
// 嚴格模式下,x沒有聲明,拋出一個錯誤
複製程式碼
程式碼如下:
(function(){
var result =eval("var x = 10, y = 20; x y"); // 嚴格模式與非嚴格模式下都能正常工作(得到30) alert(result);
}());
複製程式碼
程式碼如下:
var pPropertyerson ={};
var pPropertyerson ={}; (person,"name"{
writable:false,
value:"Nicholas" }); // 非嚴格模式下將悄無聲息地失敗,嚴格模式則拋出錯誤person.name ="John"; 這個範例中,name屬性被設定為唯讀。在非嚴格模式下,對name的賦值將悄無聲息地失敗;而在嚴格模式下,一個錯誤將被拋出。 註:如果你在使用ECMAScript屬性能力(the ECMAScript attribute capabilities),我強烈建議你開啟嚴格模式。如果你在改變物件的可變性(mutability of objects),你將遇到一堆錯誤,而它們在非嚴格模式下將被安靜地帶過。