嚴格模式和非嚴格模式區別

JinsongChai發表於2018-07-28

嚴格模式和非嚴格模式有什麼區別:

嚴格模式對正常的 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(); //報錯

總結:推薦使用嚴格模式,因為能讓程式碼更規範,也更利於後期的維護和排除錯誤。更加嚴謹。

相關文章