JavaScript 嚴格模式

在本教程中,你將學習如何在 JavaScript 中以嚴格模式執行程式碼。

什麼是嚴格模式

嚴格模式是在 ECMAScript 的 (ES5) 引入的。它是一種語義更嚴格或受限制的 JavaScript 語言版本,會為那些以靜默方式處理的錯誤產生錯誤。例如,在非嚴格模式下,如果初始化變數而不使用 var 關鍵字(例如 x = 5;) 宣告它,則 JavaScript 直譯器將假定你引用的是全域性變數,如果不存在此變數,則它將自動建立一個變數。

此外,不推薦使用的功能也可能在嚴格模式下生成錯誤。因此,嚴格模式可以減少錯誤,提高應用程式的安全性和整體效能。

啟用嚴格模式

要啟用嚴格模式,你只需在指令碼開頭新增 use strict 字串,如以下示例所示:

"use strict";

// All your code goes here
x = 5; // ReferenceError: x is not defined
console.log(x);

如果將 use strict 指令新增為 JavaScript 程式的第一行,則嚴格模式適用於整個指令碼。但是,你也可以僅在函式內開啟嚴格模式,如下所示:

x = 5;
console.log(x); // 5

function sayHello() {
    "use strict";
    str = "Hello World!"; // ReferenceError: str is not defined
    console.log(str);
}
sayHello();

注意:use strict 指令僅在指令碼或函式的開頭被識別。 use strict 除 Internet Explorer 9 及更低版本外外,所有現代瀏覽器都支援指令。此外,不支援 use strict 指令的瀏覽器會以靜默方式忽略它並以非嚴格模式解析 JavaScript。

嚴格模式下的一般限制

嚴格模式會更改語法和執行時行為。在以下部分中,我們將介紹在嚴格模式下強制執行的一般限制:

不允許使用未宣告的變數

如你所知,在嚴格模式下,必須宣告所有變數。如果為不是宣告變數的識別符號賦值,則丟擲 ReferenceError

"use strict";

function doSomething() {
    msg = "Hi, there!"; // ReferenceError: msg is not defined
    return msg;
}
console.log(doSomething());

不允許刪除變數或函式

在嚴格模式下,如果嘗試刪除變數或函式,則會引發語法錯誤。然而,在非嚴格模式下,此類嘗試以靜默方式失敗,並且 delete 表示式求值為 false

"use strict";

var person = {name: "Peter", age: 28};
delete person; // SyntaxError

同樣,當你嘗試在嚴格模式下刪除函式時,你將收到語法錯誤:

"use strict";

function sum(a, b) {
    return a + b;
}
delete sum; // SyntaxError

不允許複製引數名稱

在嚴格模式下,如果函式宣告具有兩個或多個具有相同名稱的引數,則將引發語法錯誤。在非嚴格模式下,不會發生錯誤。

"use strict";

function square(a, a) { // SyntaxError
    return a * a;
}
console.log(square(2, 2));

eval 方法不能改變範圍

在嚴格模式下,出於安全原因,傳遞給 eval() 的程式碼不能宣告/修改變數或定義周圍範圍內的函式,因為它可以在非嚴格模式下。

"use strict";

eval("var x = 5;");
console.log(x); // ReferenceError: x is not defined

evalarguments 不能用作識別符號

在嚴格模式下,名稱 evalarguments 被視為關鍵字,因此它們不能用作變數名、函式名或函式引數名等。

"use strict";

var eval = 10; // SyntaxError
console.log(eval);

不允許使用 with 語句

在嚴格模式下,不允許使用 with 語句。該 with 語句將物件的屬性和方法新增到當前範圍。因此,巢狀在 with 語句中的語句可以直接呼叫物件的屬性和方法而無需引用它。

"use strict";

// Without with statement
var radius1 = 5;
var area1 = Math.PI * radius1 * radius1;

// Using with statement
var radius2 = 5;
with(Math) { // SyntaxError
    var area2 = PI * radius2 * radius2;
} 

不允許寫入只讀屬性

在嚴格模式下,將值分配給不可寫屬性,只獲取屬性或不存在的屬性將引發錯誤。在非嚴格模式下,這些嘗試會無聲地失敗。

"use strict";

var person = {name: "Peter", age: 28};

Object.defineProperty(person, "gender", {value: "male", writable: false});
person.gender = "female"; // TypeError

不允許向不可擴充套件的物件新增新屬性

在嚴格模式下,嘗試在不可擴充套件或不可存在的物件上建立新屬性也會引發錯誤。但是在非嚴格模式下,這些嘗試會無聲地失敗。

"use strict";

var person = {name: "Peter", age: 28};

console.log(Object.isExtensible(person)); // true
Object.freeze(person); // lock down the person object
console.log(Object.isExtensible(person)); // false
person.gender = "male"; // TypeError

不允許使用八進位制數

在嚴格模式下,不允許八進位制數字。但是,在非嚴格模式下,所有瀏覽器都支援它。但是,在 ES6 中,八進位制數字由字首 0o 和數字組成,即 0o10,0o377 等。

"use strict";

var x = 010; // SyntaxError
console.log(parseInt(x));

你可以在上面的示例中清楚地看到嚴格模式如何幫助你防止在編寫 JavaScript 程式時經常被忽視的常見錯誤。

為未來的保留關鍵字被允許使用

正如你在前面章節中已經知道的那樣,保留字不能用作 JavaScript 程式中的識別符號(變數名,函式名和迴圈標籤)。除此之外,嚴格模式還對使用那些為將來保留的關鍵字施加限制。

按照最新的 ECMAScript 6(或 ES6)標準,這些關鍵字是保留的關鍵字,當他們在嚴格模式程式碼被發現: awaitimplementsinterfacepackageprivateprotectedpublic ,和 static 。但是,為了獲得最佳相容性,應避免在程式中將保留關鍵字用作變數名或函式名。

提示: 保留字,這也是所謂的關鍵字,是屬於 JavaScript 語言語法的一部分,例如特殊字詞, varifforfunction 等。請參照 JS 保留關鍵字參考 為 JavaScript 中的保留字的完整列表。