JS里有兩種運行模式,一種是正常運行模式,平時基本上用的也都是正常模式,另外一種是嚴格模式,strict mode,嚴格模式是ECMAscript 5添加,這種模式能讓JS在更嚴格的條件下運行
嚴格模式的提出有以下幾個目的:
1.消除了一些JS不合理,不嚴謹之處,減少一些怪異行為,保證代碼安全運行
2.提高了編譯器效率,增加運行速度
3.為未來新版本JS做好鋪墊
1.嚴格模式標志和使用
進入嚴格模式的標志,就是需要加上一個字符串:"use strict".如果是老版本的瀏覽器,像IE6789,就把這句話當成一句普通的字符串執行.
嚴格模式根據不同的作用域,有不同的調用方法
(1).針對整個腳本文件
將"use strict"放在腳本文件的第一行,則整個腳本都將以"嚴格模式"運行。如果這行語句不在第一行,則無效,整個腳本以"正常模式"運行。如果不同模式的代碼文件合并成一個文件,這一點需要特別注意。
第一種是針對整個腳本文件
<script>
"use strict";
console.log("這是嚴格模式。");
</script>
第二種是針對單個函數,將"use strict"放在函數體的第一行,則整個函數以"嚴格模式"運行。
function strict(){
"use strict";
return "這是嚴格模式。";
}
如果是放在自調用的匿名函數里話,用法也一樣,這種寫法主要是為了解決之前文件合并出現的問題.
(function (){
"use strict";
// some code here
})();
2.全局變量顯式聲明
在正常模式里,如果一個變量沒有聲明,那這個變量可以認為是全局變量,但是在嚴格模式下,這種寫法就會報錯,變量在使用之前,一定得先定義,全局變量.
"use strict";
v = 1; // 報錯,v未聲明
for(i = 0; i < 2; i++) { // 報錯,i未聲明
}
3.with語句
下面要用到這個with語句,先解釋一下.with語句能快速的使用一個對象的屬性,不需要每次都通過對象名.
function Lakers() {
this.name = "龍哥";
this.age = "18";
this.gender = "boy";
}
var people = new Lakers();
with(people) {
var str = "姓名: " + name;
str += "年齡:" + age;
str += "性別:" + gender;
document.write(str);
}
用with語句相當于進入了people的內容去獲取屬性內容,在people這個對象的作用域中去使用屬性
4.嚴格模式禁止使用with語句
原因在于with語句在編譯的時候,沒有辦法確認這個傳進來的對象的歸屬,這種寫法在嚴格模式里是嚴格禁止的,只要在上面的例子最上面加上"use strict";在瀏覽器控制臺就會報錯
嚴格模式不允許進行動態綁定,也就是要指明屬性和方法歸屬于哪個對象,在編譯階段就要確定.with就是違背了上述的要求
5.eval()函數
eval函數可以計算某個字符串,執行其中的JS代碼.eval()只需要一個參數,類型必須是字符串,如果參數不是字符串,則直接返回這個參數.如果是字符串,直接執行字符串對應的JS表達式和語句,如果有計算記過,eval()則會返回對應結果
eval("x=10;y=20;document.write(x*y)");
document.write(eval("2+2"));
var x=10;
document.write(eval(x+17));
接下來看一下eval關于作用域的問題
<script type="text/javascript">
var test = function () {
eval("var i=3");
alert(i);
}
test();
alert(i);
</script>
結果是首先彈出3,然后是undefined,eval()函數動態執行的代碼并不會創建新的作用域,其代碼就是在當前的作用域執行的。因此也就是說,eval()函數也完全可以使用當前作用域的this,argument等對象.
在IE里有一個根eval()函數很相似的函數,叫execScript(),作用大同小異,但是它有兼容問題,在Chrome和Firefox上不兼容,兼容的寫法跟addEventListener類似,就不寫了
6.嚴格模式設置了eval作用域
正常模式下,JS有三個作用域,一個是全局作用域,一個是函數函數作用域,在ES6里,已經有塊作用域了.嚴格模式創設了第三種作用域,就是eval作用域.在嚴格模式下,eval本身就是一個作用域,不再能夠生成全局變量了,它所生成的變量只能用于eval內部
"use strict";
var x = 2;
console.log(eval("var x = 5; x")); // 5
console.log(x); // 2
7.重名錯誤
這里的重名只要值的是函數里不能有重復的形參名
"use strict";
function f(a, a, b) { // 語法錯誤
return;
}
對象里有重復的屬性,不會報錯,答應的對象就會保留一個屬性,聲明重復變量名也不會報錯
8.禁止this指向全局變量
在函數里,this一般都指向是window這個全局變量,但是在嚴格模式下,this的值變為undefined.
function f() {
"use strict";
console.log(this); // undefined
};
現在JS已經進入了ES6,有些內容會發生一點變化,比如之前會新增一些保留字,比如let,interface,implements等,都出現在ES6里.在接觸過RN等新技術之后大家會發現,嚴格模式用的還是比較多的.