ES5最先引入了嚴格模式的概念。經過嚴格模式,能夠在函數內部選擇較爲嚴格的全局或局部的錯誤條件檢測。使用嚴格模式的好處是,能夠提前地發現函數內部存在的錯誤以及編譯中產生的錯誤。 支持嚴格模式的瀏覽器包括IE10+、FireFox4+、Safari5.1+和Chrome。javascript
使用編譯指示,實際上就是一個字符串:"use strict";
若是在全局做用域中(函數外部)使用這個編譯指示,則整個腳本都將使用嚴格模式。 也就是說,若是把帶有嚴格模式的腳本放在其餘文件中,那麼這個文件下的JS代碼也會處於嚴格模式下。 也能夠在函數中打開嚴格模式,java
function fn() {
"use strict";
// more codes
}
複製代碼
在嚴格模式下,何時建立變量以及怎麼建立變量都是有限制的。瀏覽器
不容許意外建立全局變量,必需要有一個聲明。app
var msg = "Hello!";
複製代碼
不能對變量調用delete操做符。在非嚴格模式下會靜默失敗,可是不會報錯。而在嚴格模式下會報錯。函數
嚴格模式下,不能使用implements、interface、let、package、private、protected、public、static、yield等保留字做爲變量名。ui
在非嚴格模式下,操做對象時有些錯誤會靜默失敗,而在嚴格模式下就會報錯。 如下狀況時操做對象會報錯:this
另外嚴格模式下,在經過對象字面量形式來聲明對象時,屬性名必須惟一,不然會報錯。spa
var person = {
name: 'Knight',
name: 'Bill'
} // Error
複製代碼
function add(a, a) {
// dosomething
}
複製代碼
解析: 上面這段函數聲明在非嚴格模式下是不會報錯的。 嚴格模式下,經過參數名只能訪問第二個參數,第一個參數必須經過**arguments對象(形參列表)**進行訪問。code
在嚴格模式下,arguments對象的行爲和非嚴格模式是有區別的。 在非嚴格模式下,修改命名參數的值會反映到arguments對象中,可是在嚴格模式下這兩個值是相互獨立的。cdn
function showName(name) {
name = 'Mike',
console.log(name); // 'Mike'
console.log(arguments[0]); // 非嚴格模式:'Mike'; 嚴格模式: 'Bill'
}
showName('Bill');
複製代碼
解析:在調用函數時,首先會傳入實參值'Bill',並寫入arguments對象中。 在非嚴格模式下,函數內部將name值從新賦值爲'Mike',所以arguments[0]的值也被同時修改成'Mike'。 而在嚴格模式下,arguments[0]的值依然是'Bill'。
在非嚴格模式下,這兩個屬性一個引用函數自己,一個引用調用函數。 而在嚴格模式下,這兩個屬性被淘汰,使用時均會報錯。
// 求一個階乘
function fn(num) {
if(num <= 1) {
return 1;
}else {
return num * arguments.callee(num-1);
}
}
console.log(fn(3)); // 3! = 6
複製代碼
解析: 這是一個求階乘的函數,在非嚴格模式下,調用函數時,可用arguments.callee()來調用函數自己,從而實現函數功能。 而在嚴格模式下則會報錯。
嚴格模式下,不能使用implements、interface、let、package、private、protected、public、static、yield等保留字做爲函數變量名。
在嚴格模式下,只能在腳本的頂級和在函數內部聲明函數。也就是說,在if語句/for語句中,聲明函數是會報錯的。
"use strict";
if (true) {
function f() { } // !!! 語法錯誤
f();
}
for (var i = 0; i < 5; i++) {
function f2() { } // !!! 語法錯誤
f2();
}
function baz() { // 合法
function eit() { } // 一樣合法
}
複製代碼
eval()在包含上下文中再也不建立變量和函數。
function fn() {
eval("var x = 123;");
console.log(x);
}
fn();
複製代碼
解析:上述代碼在嚴格模式下是會報錯的(ReferenceError),而在非嚴格模式下正常運行。
嚴格模式不容許使用eval和arguments做爲標識符,也不容許讀寫它們的值。
var eval = 'hello';
var arguments = 'world';
複製代碼
解析:這在非嚴格模式下是能夠解析運行的,可是在嚴格模式下會報錯。 所以,不能將它們用做標識符,如下幾種狀況均會拋出語法錯誤:
在非嚴格模式下使用apply()或者call()方法時,null和undefined值會轉換爲全局對象。 而在嚴格模式下,函數的this值始終是指定的值,不管指定的是什麼值。
var color = "red";
function displayColor() {
console.log(this.color);
}
displayColor.call(null);
複製代碼
解析: 在非嚴格模式下,displayColor.call()中傳入了null,那麼此時函數的this是全局對象,所以會打印出red。 而在嚴格模式下,這個函數的this就是null,所以在訪問null的屬性時會報錯。
非嚴格模式下,with語句能夠改變解析標識符的路徑,可是在嚴格模式下,with被簡化,會報錯。
with(location) {
alert(href);
}
複製代碼
以0開頭的八進制字面量過去常常會致使不少錯誤。 所以,在嚴格模式下,八進制字面量已經被拋棄。
var val = 010;
複製代碼
在ES5標準的嚴格模式下,八進制字面量會被當作以0開頭的十進制字面量。
var val = parseInt("010");
console.log(val); // 10
複製代碼