JavaScript 嚴格模式

admin發表於2017-11-02

所謂的嚴格模式是在ECMA-262 Edition 5中新增的語法,表示要用嚴格的javascript語法來執行程式碼。

下面將繼續簡單介紹一下嚴格模式的一些相關內容。

一.宣告嚴格模式:

使用以下語句可以宣告嚴格模式:

[JavaScript] 純文字檢視 複製程式碼
"use strict";

特別說明:

在老舊的瀏覽器中,javascript會將其處理為一行普通的字串。

二.嚴格模式的作用範圍:

嚴格模式的作用範圍和宣告嚴格模式的語句有著直接的關係。嚴格模式宣告語句只會在它所在的作用域中有效。

如果"use strict";語句在函式中,那麼嚴格模式的影響只會侷限於當前函式內,此函式外的其他javascript程式碼不會受到影響。

如果在全域性作用域中宣告嚴格模式,那麼所有的javascript程式碼都會處於嚴格模式中。

程式碼例項:

例項一:

[JavaScript] 純文字檢視 複製程式碼
"use strict";
console.log("螞蟻部落");

上面的程式碼中,將會宣告整個指令碼都採用嚴格模式。

特別說明:

宣告語句必須要放在指令碼的第一行,否則會無效,整個指令碼將會以普通的模式執行。當然這個第一行也不是特別的絕對,如果"use strict";語句前面不是產生實際執行結果的語句,那麼它可以不是在第一行,例如:

[JavaScript] 純文字檢視 複製程式碼
;"use strict";
console.log("螞蟻部落");

上面的宣告語句前面跟著一個空語句。

例項二:

[JavaScript] 純文字檢視 複製程式碼
function func(){
  "use strict";
  return "螞蟻部落";
}

上面的程式碼將會宣告此函式內將會採用嚴格模式。

三.嚴格模式對語法有哪些變化:

原來在普通模式下生效的程式碼,可能在嚴格模式下就會報錯,下面就簡單介紹一下嚴格模式下有哪些主要的語法上的變化。

1.變數要顯示宣告:

在普通模式下,宣告一個變數可以不適用var,那麼這個變數是全域性性的,但是在嚴格模式下,宣告變數必須採用顯式宣告,前面必須要有var,否則會報錯。

[JavaScript] 純文字檢視 複製程式碼
"use strict";
antzone="螞蟻部落";

上面的程式碼會報錯,宣告變數要使用var。

2.關於動態繫結的限制:

在普通模式下,對於"動態繫結"是非常的靈活寬鬆的。

所謂的"動態繫結"就是一些屬性或者方法是屬於哪個物件,不是在編譯階段確定的,而是在執行階段。

嚴格模式對"動態繫結"做了一定的限制,也就是說屬性或者方法屬於哪個物件是在編譯階段就會被確定,優點是能夠提高編譯的效率,程式碼也更為安全。下面就是幾個具體的規定:

(1).禁止使用width語句:

[JavaScript] 純文字檢視 複製程式碼
"use strict";
var antzone = 1;
with (obj){ 
  antzone = 2;
}

上面的程式碼會報錯。

(2).eval()函式的作用域問題:

在普通模式下,分為區域性作用域和全域性作用語兩種形式。

eval語句的作用域取決於它是處於全域性作用域還是區域性作用域,但是在嚴格模式下,eval()會單獨形成一個作用域,由它產生的變數只能用於它的內部,程式碼如下:

[JavaScript] 純文字檢視 複製程式碼
"use strict";
var antzone=5;
//下面語句輸出6
console.log(eval("var antzone= 6;antzone"));
//下面語句輸出5
console.log(antzone);

3.加強安全性:

(1).禁止this指向window物件:

在普通模式下,函式中的this是可以指向全域性物件的,但是在嚴格模式下是不允許的。

程式碼如下:

[JavaScript] 純文字檢視 複製程式碼
function func(){
  "use strict";
  return !this;
}
func();

此函式的返回值是true,因為這個時候this的值是undefined,所以!this的值就是true。

(2).禁止在函式內部遍歷呼叫棧:

[JavaScript] 純文字檢視 複製程式碼
function func(){
  "use strict";
  func.caller;//報錯
  func.arguments;//報錯
}
func();

4.限制刪除變數:

在普通模式下,可以使用delete語句刪除變數和屬性,但是在嚴格模式下這裡做了一些限制。

只有configurable屬性值為true的物件屬性才能夠被刪除。

[JavaScript] 純文字檢視 複製程式碼
"use strict";
var antzone;
delete antzone;//語法錯誤
var obj=Object.create(null,'x',{
  value:1,
  configurable:true
});
delete obj.x;//刪除成功

5.更嚴格錯誤報告:

(1).如果一個物件的屬性是隻讀的,在普通模式下,如果對其賦值,這個時候也是不會報錯的,但是在嚴格模式下將會報錯。

程式碼如下:

[JavaScript] 純文字檢視 複製程式碼
"use strict";
var obj={};
Object.defineProperty(obj,"v",{value:1,writable:false});
obj.v=2;

(2).如果一個屬性是使用getter方法進行讀取的,如果對齊進行賦值也會報錯。

程式碼如下:

[JavaScript] 純文字檢視 複製程式碼
"use strict";
var obj = {
  get v() { return 1; }
};
obj.v = 2; // 報錯

(3).如果為一個禁止進行擴充套件的物件新增屬性,也會報錯。

程式碼如下:

[JavaScript] 純文字檢視 複製程式碼
"use strict";
var o={};
Object.preventExtensions(o);
o.v=1;// 報錯

(4).物件不能有兩個重複的屬性名稱,否則會報錯。

程式碼如下:

[JavaScript] 純文字檢視 複製程式碼
"use strict";
var obj = {
  antzone: "螞蟻部落",
  antzone: "分享互助"
};

(5).函式的引數不能夠有重複的,否則會報錯。

程式碼如下:

[JavaScript] 純文字檢視 複製程式碼
"use strict";
function funct(num, num, m) {
  return ;
}

(6).在嚴格模式下禁止使用八進位制表示法,否則會報錯。

程式碼如下:

[JavaScript] 純文字檢視 複製程式碼
"use strict";
var num = 0100;

6.對於arguments物件的一些限制:

在嚴格模式下,對於arguments物件做了一些特別的限制,下面就簡單做一下介紹。

(1).此物件不再追蹤函式引數的變化,程式碼如下:

[JavaScript] 純文字檢視 複製程式碼
function func(num){
  num=2;
  return [num,arguments[0]];
}
console.log(func(5))

上面是普通模式下,呼叫函式時候傳遞的值是5,但是在函式內部做了修改,這個時候能夠跟蹤變化。但是在嚴格模式下,引數的變化是不會不追蹤的,呼叫的時候傳入的是什麼最終還是什麼。

(2).禁止使用arguments.callee:

在嚴格模式下arguments.callee是被禁止使用的。

7.關於函式的宣告:

在嚴格模式下,函式的宣告在全域性作用域下,由於javascript會在新版本可能會引入塊級作用域,也就是說函式不能夠宣告在出去函式之外的非全域性作用域下,程式碼如下:

[JavaScript] 純文字檢視 複製程式碼
"use strict";
if(true) {
  function f(){ }
}
for (var i = 0; i < 5; i++) {
  function f2() { }
}

在上面的程式碼中,由於函式不能夠宣告在塊級作用域,所以會報錯。

8.保留字:

在新的javascript版本中,現在的保留字可能會有其他語法用途,所以在嚴格模式下禁止將保留字用作變數名。

保留字列表如下:

[JavaScript] 純文字檢視 複製程式碼
implements, interface, let, package, private, protected, public, static, yield

相關文章