嚴格模式和非嚴格模式有什麼區別:
嚴格模式對正常的 JavaScript語義做了一些更改。
首先,嚴格模式通過丟擲錯誤來消除了一些原有靜默錯誤。
其次,嚴格模式修復了一些導致 JavaScript引擎難以執行優化的缺陷:有時候,相同的程式碼,嚴格模式可以比非嚴格模式下執行得更快。
第三,嚴格模式禁用了在ECMAScript的未來版本中可能會定義的一些語法。
上文引用了MDN對嚴格模式的描述
1.變數必須宣告才能使用(在正常模式中,如果一個變數沒有宣告就賦值,預設是全域性變數。嚴格模式禁止這種寫法)
2.禁止使用with語句(因為with語句無法在編譯時就確定,屬性到底歸屬於哪個物件,嚴格模式有利於編譯效率提高)
3.建立eval作用域(正常模式下,js有兩種變數作用域,全域性作用域和區域性作用域,正常模式下eval語句作用域取決於它處於全域性作用域還是函式作用域,嚴格模式下eval語句本身就是作用域,不能夠生成全域性變數,所生成的變數只能用於eval內部)
4.禁止this關鍵字指向全域性物件(嚴格模式下全域性作用域中定義的函式中的this為undefined)。例如:
function f(){
return !this; //返回的是false,因為this指向的是全域性物件,!物件 == false
}
function f(){
"use strict"
return !this; //返回的是true,因為嚴格模式下,this的值為undefined,!undefined == true
}
5.禁止在函式內部遍歷呼叫棧( caller:呼叫當前函式的函式的引用,即外層函式的引用; )
function f1(){
"use strict";
f1.caller; //報錯
f1.arguments; //報錯
}
f1();
6.嚴格模式下無法刪除變數。只有conifgurable設定為true的物件屬性才能被刪除
"use strict"
var x ;
delete x; //嚴格模式下報語法錯誤
var o = Object.create(null,{'x':{
value: 1,
configurable: true
}})
delete o.x; //刪除成功
7.顯示報錯(正常模式下對一個物件的只讀屬性進行賦值,不會報錯,只會默默失敗。嚴格模式下將報錯)
"use strict";
var o = {};
Object.defineProperty(o,"v",{value: 1,writable: false});
o.v = 2; //報錯,因為o.v屬性是不能被修改的,嚴格模式會報錯,正常模式會失敗但不報錯
8.嚴格模式下,對禁止擴充套件的物件新增新屬性,會報錯
"use strict";
var o = {};
Object.preventExtensions(o);//禁止o物件有擴充屬性
o.v = 1; //報錯
9.嚴格模式下,刪除一個不可刪除的屬性,報錯
"use strict";
delete Object.prototype; //報錯
10.物件擁有多個同名屬性,嚴格模式報錯。正常模式會預設值為最後一個
11.函式不能有重名的引數,嚴格模式會報錯,正常模式可以通過arguments[i]來獲取對應的引數
12.禁止八進位制寫法,正常情況下整數第一位為0代表八進位制,嚴格模式下整數第一位為0則報錯
13.不準對arguments賦值
14.嚴格模式下的arguments不在追蹤引數的變化
function fn(a){
a=2;
return [a,arguments[0]];
}
fn(1); //正常模式返回值 [2,2]
"use strict"
function fn(a){
a = 2;
return [a,arguments[0]];
}
fn(1); //嚴格模式返回值 [2,1] 引數傳進來是多少就是多少,arguments不會變化
15.禁止使用arguments.callee(無法在匿名函式內部呼叫自身了。arguments.callee指向的就是該函式本身)
var f = function (){
return arguments.callee;
}
f(); //報錯
總結:推薦使用嚴格模式,因為能讓程式碼更規範,也更利於後期的維護和排除錯誤。更加嚴謹。