摘要:
ECMAScript5中引入的嚴格模式,通過讓JavaScript運行環境對一些開發過程中最常見和不易發現的錯誤做出和當前不同的處理,來讓開發者擁有一個”更好”的JavaScript語言。但目前為止,所有主流的瀏覽器都在他們的高版本中支持了嚴格模式,包括IE10、Firefox4、chrome12、Opera12、Android4和IOS5。
嚴格模式是一個更好的方法引入檢查錯誤代碼。使用嚴格的模式時,您不能,例如,使用隱式聲明變量,給只讀屬性賦值,或將屬性添加到一個不可擴展的對象中。
聲明嚴格模式:
你可以宣布嚴格模式通過添加“use strict”;在一個文件、一個程序或一個函數的開始。這種聲明稱為指令序言。嚴格模式聲明的范圍取決於它的上下文。如果它是宣布在全局上下文(一個函數的范圍之外),程序的所有代碼在嚴格的模式下執行。如果在一個函數內聲明它,則函數內所有的代碼在嚴格模式下執行。例如,在下面的示例中所有的代碼都是在嚴格模式下,函數外聲明的變量導致語法錯誤“變量未定義的嚴格模式”。
1 "use strict"; 2 function testFunction(){ 3 var testvar = 4; 4 return testvar; 5 } 6 // This causes a syntax error. 7 testvar = 5;
在接下來的例子中,只有testFunction里面的代碼在嚴格模式下執行。函數外的變量未聲明不會導致一個語法錯誤,但在函數內會導致語法錯誤。
1 function testFunction(){ 2 "use strict"; 3 // This causes a syntax error. 4 testvar = 4; 5 return testvar; 6 } 7 testvar = 5;
注意:
- 如果瀏覽器不支持嚴格模式會忽略"use strict"這個字符串。這樣就允許跨瀏覽器的使用嚴格模式語法,這是為了保證向前兼容,防止有一天某些瀏覽器僅僅支持嚴格模式。測試你的瀏覽器是否支持嚴格模式
- 當嚴格模式的方法調用了一個非嚴格方法時,該非嚴格方法不會啟用嚴格模式,因為非嚴格方法被當作參數傳遞或是通過call和apply調用
- 當嚴格模式的方法調用了一個非嚴格方法時,該非嚴格方法不會啟用嚴格模式,因為非嚴格方法被當作參數傳遞或是通過call和apply調用
嚴格模式的利與弊:
- 優點:
提高編譯器效率,增加運行速度
消除Javascript語法的一些不合理、不嚴謹之處,減少一些怪異行為
消除代碼運行的一些不安全之處,保證代碼運行的安全 - 缺點:
在"嚴格模式"中,同樣的代碼可能會有不一樣的運行結果
一些在"正常模式"下可以運行的語句,在"嚴格模式"下將不能運行
嚴格模式的限制:
下表列出了在嚴格模式最重要的限制
| Language element |
Restriction |
Error |
Example |
| Variable |
Using a variable without declaring it. |
SCRIPT5042: Variable undefined in strict mode |
testvar = 4; |
| Read-only property |
Writing to a read-only property. |
SCRIPT5045: Assignment to read-only properties is not allowed in strict mode |
var testObj = Object.defineProperties({}, {
prop1: {
value: 10,
writable: false // by default
},
prop2: {
get: function () {
}
}
});
testObj.prop1 = 20;
testObj.prop2 = 30; |
| Non-extensible property |
Adding a property to an object whoseextensibleattribute is set to false. |
SCRIPT5046: Cannot create property for a non-extensible object |
var testObj = new Object(); Object.preventExtensions(testObj); testObj.name = "Bob"; |
| delete |
Deleting a variable, a function, or an argument. Deleting a property whoseconfigurableattribute is set to false. |
SCRIPT1045: Calling delete on <expression>is not allowed in strict mode |
var testvar = 15;function testFunc() {};delete testvar;delete testFunc;
Object.defineProperty(testObj, "testvar", {
value: 10,
configurable: false
});delete testObj.testvar; |
| Duplicating a property |
Defining a property more than once in an object literal. |
SCRIPT1046: Multiple definitions of a property not allowed in strict mode |
var testObj = {
prop1: 10,
prop2: 15,
prop1: 20
}; |
| Duplicating a parameter name |
Using a parameter name more than once in a function. |
SCRIPT1038: Duplicate formal parameter names not allowed in strict mode |
function testFunc(param1, param1) { return 1;
}; |
| Future reserved keywords |
Using a future reserved keyword as a variable or function name. |
SCRIPT1050: The use of a future reserved word for an identifier is invalid. The identifier name is reserved in strict mode. |
|
| Octals |
Assigning an octal value to a numeric literal, or attempting to use an escape on an octal value. |
SCRIPT1039: Octal numeric literals and escape characters not allowed in strict mode |
var testoctal = 010;var testescape = \010; |
| this |
The value ofthis is not converted to the global object when it is null orundefined. |
function testFunc() { In non-strict mode, the value of testvar is the global object, but in strict mode the value is undefined. |
|
| evalas an identifier |
The string "eval" cannot be used as an identifier (variable or function name, parameter name, and so on). |
var eval = 10; |
|
| Function declared inside a statement or a block |
You cannot declare a function inside a statement or a block. |
SCRIPT1047: In strict mode, function declarations cannot be nested inside a statement or block. They may only appear at the top level or directly inside a function body. |
var arr = [1, 2, 3, 4, 5]; |
| Variable declared inside an evalfunction |
If a variable is declared inside anevalfunction, it cannot be used outside that function. |
SCRIPT1041: Invalid usage of 'eval' in strict mode |
eval("var testvar = 10");
testvar = 15; Indirect evaluation is possible, but you still cannot use a variable declared outside the eval function. var indirectEval = eval;
indirectEval("var testvar = 10;");
document.write(testVar); This code causes an error SCRIPT5009: 'testVar' is undefined. |
| Argumentsas an identifier |
The string "arguments" cannot be used as an identifier (variable or function name, parameter name, and so on). |
SCRIPT1042: Invalid usage of 'arguments' in strict mode |
var arguments = 10; |
| argumentsinside a function |
You cannot change the values of members of the localargumentsobject. |
function testArgs(oneArg) {
arguments[0] = 20;
} In non-strict mode, you can change the value of the oneArgparameter by changing the value of arguments[0], so that the value of both oneArg and arguments[0] is 20. In strict mode, changing the value of arguments[0] does not affect the value of oneArg, because the arguments object is merely a local copy. |
|
| arguments.callee |
Not allowed. |
function (testInt) { |
|
| with |
Not allowed. |
SCRIPT1037: 'with' statements are not allowed in strict mode |
with (Math){
x = cos(3);
y = tan(7);
} |
