JS里有兩種運(yùn)行模式,一種是正常運(yùn)行模式,平時(shí)基本上用的也都是正常模式,另外一種是嚴(yán)格模式,strict mode,嚴(yán)格模式是ECMAscript 5添加,這種模式能讓JS在更嚴(yán)格的條件下運(yùn)行
嚴(yán)格模式的提出有以下幾個(gè)目的:
1.消除了一些JS不合理,不嚴(yán)謹(jǐn)之處,減少一些怪異行為,保證代碼安全運(yùn)行
2.提高了編譯器效率,增加運(yùn)行速度
3.為未來(lái)新版本JS做好鋪墊
1.嚴(yán)格模式標(biāo)志和使用
進(jìn)入嚴(yán)格模式的標(biāo)志,就是需要加上一個(gè)字符串:"use strict".如果是老版本的瀏覽器,像IE6789,就把這句話當(dāng)成一句普通的字符串執(zhí)行.
嚴(yán)格模式根據(jù)不同的作用域,有不同的調(diào)用方法
(1).針對(duì)整個(gè)腳本文件
將"use strict"放在腳本文件的第一行,則整個(gè)腳本都將以"嚴(yán)格模式"運(yùn)行。如果這行語(yǔ)句不在第一行,則無(wú)效,整個(gè)腳本以"正常模式"運(yùn)行。如果不同模式的代碼文件合并成一個(gè)文件,這一點(diǎn)需要特別注意。
第一種是針對(duì)整個(gè)腳本文件
<script>
"use strict";
console.log("這是嚴(yán)格模式。");
</script>
第二種是針對(duì)單個(gè)函數(shù),將"use strict"放在函數(shù)體的第一行,則整個(gè)函數(shù)以"嚴(yán)格模式"運(yùn)行。
function strict(){
"use strict";
return "這是嚴(yán)格模式。";
}
如果是放在自調(diào)用的匿名函數(shù)里話,用法也一樣,這種寫法主要是為了解決之前文件合并出現(xiàn)的問(wèn)題.
(function (){
"use strict";
// some code here
})();
2.全局變量顯式聲明
在正常模式里,如果一個(gè)變量沒(méi)有聲明,那這個(gè)變量可以認(rèn)為是全局變量,但是在嚴(yán)格模式下,這種寫法就會(huì)報(bào)錯(cuò),變量在使用之前,一定得先定義,全局變量.
"use strict";
v = 1; // 報(bào)錯(cuò),v未聲明
for(i = 0; i < 2; i++) { // 報(bào)錯(cuò),i未聲明
}
3.with語(yǔ)句
下面要用到這個(gè)with語(yǔ)句,先解釋一下.with語(yǔ)句能快速的使用一個(gè)對(duì)象的屬性,不需要每次都通過(guò)對(duì)象名.
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語(yǔ)句相當(dāng)于進(jìn)入了people的內(nèi)容去獲取屬性內(nèi)容,在people這個(gè)對(duì)象的作用域中去使用屬性
4.嚴(yán)格模式禁止使用with語(yǔ)句
原因在于with語(yǔ)句在編譯的時(shí)候,沒(méi)有辦法確認(rèn)這個(gè)傳進(jìn)來(lái)的對(duì)象的歸屬,這種寫法在嚴(yán)格模式里是嚴(yán)格禁止的,只要在上面的例子最上面加上"use strict";在瀏覽器控制臺(tái)就會(huì)報(bào)錯(cuò)

嚴(yán)格模式不允許進(jìn)行動(dòng)態(tài)綁定,也就是要指明屬性和方法歸屬于哪個(gè)對(duì)象,在編譯階段就要確定.with就是違背了上述的要求
5.eval()函數(shù)
eval函數(shù)可以計(jì)算某個(gè)字符串,執(zhí)行其中的JS代碼.eval()只需要一個(gè)參數(shù),類型必須是字符串,如果參數(shù)不是字符串,則直接返回這個(gè)參數(shù).如果是字符串,直接執(zhí)行字符串對(duì)應(yīng)的JS表達(dá)式和語(yǔ)句,如果有計(jì)算記過(guò),eval()則會(huì)返回對(duì)應(yīng)結(jié)果
eval("x=10;y=20;document.write(x*y)");
document.write(eval("2+2"));
var x=10;
document.write(eval(x+17));
接下來(lái)看一下eval關(guān)于作用域的問(wèn)題
<script type="text/javascript">
var test = function () {
eval("var i=3");
alert(i);
}
test();
alert(i);
</script>
結(jié)果是首先彈出3,然后是undefined,eval()函數(shù)動(dòng)態(tài)執(zhí)行的代碼并不會(huì)創(chuàng)建新的作用域,其代碼就是在當(dāng)前的作用域執(zhí)行的。因此也就是說(shuō),eval()函數(shù)也完全可以使用當(dāng)前作用域的this,argument等對(duì)象.
在IE里有一個(gè)根eval()函數(shù)很相似的函數(shù),叫execScript(),作用大同小異,但是它有兼容問(wèn)題,在Chrome和Firefox上不兼容,兼容的寫法跟addEventListener類似,就不寫了
6.嚴(yán)格模式設(shè)置了eval作用域
正常模式下,JS有三個(gè)作用域,一個(gè)是全局作用域,一個(gè)是函數(shù)函數(shù)作用域,在ES6里,已經(jīng)有塊作用域了.嚴(yán)格模式創(chuàng)設(shè)了第三種作用域,就是eval作用域.在嚴(yán)格模式下,eval本身就是一個(gè)作用域,不再能夠生成全局變量了,它所生成的變量只能用于eval內(nèi)部
"use strict";
var x = 2;
console.log(eval("var x = 5; x")); // 5
console.log(x); // 2
7.重名錯(cuò)誤
這里的重名只要值的是函數(shù)里不能有重復(fù)的形參名
"use strict";
function f(a, a, b) { // 語(yǔ)法錯(cuò)誤
return;
}
對(duì)象里有重復(fù)的屬性,不會(huì)報(bào)錯(cuò),答應(yīng)的對(duì)象就會(huì)保留一個(gè)屬性,聲明重復(fù)變量名也不會(huì)報(bào)錯(cuò)
8.禁止this指向全局變量
在函數(shù)里,this一般都指向是window這個(gè)全局變量,但是在嚴(yán)格模式下,this的值變?yōu)閡ndefined.
function f() {
"use strict";
console.log(this); // undefined
};
現(xiàn)在JS已經(jīng)進(jìn)入了ES6,有些內(nèi)容會(huì)發(fā)生一點(diǎn)變化,比如之前會(huì)新增一些保留字,比如let,interface,implements等,都出現(xiàn)在ES6里.在接觸過(guò)RN等新技術(shù)之后大家會(huì)發(fā)現(xiàn),嚴(yán)格模式用的還是比較多的.