javascript 嚴格模式


嚴格模式是一種特殊的執行模式,它修復了部分語言上的不足,提供更強的錯誤檢查,並增強安全性。

一、如何使用嚴格模式?

可以在js文件的最開頭寫入,這樣就會在整個js文件中使用嚴格模式

“use strict”;
function func(){
}  

或者在一個函數的開頭寫入,這樣會在這個函數內使用嚴格模式

function func(){
  "use strict";  
}

二、嚴格模式與普通模式的區別

1、嚴格模式下,不允許用with

!function(){
  	with({x:1}){
        console.log(x);//1
    }  
}();

在嚴格模式下使用with會報一個SyntaxError 語法錯誤

!function(){
	"use strict";
  	with({x:1}){
        console.log(x);
    }  
}();
//SyntaxError: Strict mode code may not include a with statement

 

2、嚴格模式下,不允許未聲明的變量被賦值

在普通模式下:

 

!function(){
	x=1;
	console.log(window.x);//1
}();

 

沒有使用var聲明變量,而是直接給變量賦值,相當於聲明了一個全局變量。

在嚴格模式下:

!function(){
	"use strict";
	x=1;
	console.log(window.x);
}();
//Uncaught ReferenceError: x is not defined

沒有用var給變量聲明而是直接賦值,會報一個ReferenceError錯誤  

  

 

3、嚴格模式下,arguments變為參數的靜態副本

在普通模式下:

!function(a){
	arguments[0]=100;	
	console.log(a);//100
}(1);

定義了函數,並且傳參,比如形參a和arguments[0]是有相互綁定關系的,如果修改了arguments[0]為100,那么對應的形參a也會被修改。需要注意的是,如果不給形參傳值,比如這里的1不傳,那么a的值是undefined,arguments[0]修改為100的話,a的值依然是undefined,不受arguments所影響。

!function(a){
	arguments[0]=100;	
	console.log(a);//undefined
}();

在嚴格模式下:

!function(a){
	"use strict";
	arguments[0]=100;	
	console.log(a);//1
}(1);

 

!function(a){
	"use strict";
	arguments[0]=100;	
	console.log(a);//undefined
}();

arguments已經變成了參數的靜態副本,不管參數有沒有傳值,都不會和arguments相互影響。

但如果傳入的參數是對象,修改對象的屬性,仍然是會相互影響的。

!function(a){
	"use strict";
	arguments[0].x=100;	
	console.log(a.x);//100
}({x:1});

  

4、嚴格模式下,delect參數、函數名報錯

在普通模式下:

!function(a){		
	console.log(delete a);//false
}(1);

刪除一個參數會返回false,刪除不成功。

在嚴格模式下:

!function(a){
	"use strict";		
	delete a;
}(1);
//Uncaught SyntaxError: Delete of an unqualified identifier in strict mode.

刪除一個參數或函數名會報一個SyntaxError語法錯誤。

 

5、嚴格模式下,delete不可配置的屬性報錯

在普通模式下:

!function(a){
	var obj={};
	Object.defineProperty(obj,"a",{
		configurable:false
	});
	console.log(delete obj.a);//false
}(1);

刪除一個configurable為false的屬性,返回false,並且刪除失敗。  

在嚴格模式下:

!function(a){
	"use strict";
	var obj={};
	Object.defineProperty(obj,"a",{
		configurable:false
	});
	delete obj.a;
}(1);
//Uncaught TypeError: Cannot delete property 'a' of #<Object>

試圖刪除configurable為false 的屬性的話,會報一個TypeError的錯誤。  

  

6、嚴格模式下,重名錯誤

(1)對象字面量重復屬性名報錯

在普通模式下: 

!function() {
    var obj = {x : 1, x : 2};
    console.log(obj.x);//2
}();

在嚴格模式下:

!function() {
    'use strict';
    var obj = {x:1,x:2,x:3};
    console.log(obj.x);//3
}();

網上說會報SyntaxError錯誤,本人測試嚴格模式下木有問題,不知道啥情況。

(2)函數不能有重名的參數:

!function(a,a,b){
    "use strict";
    return false;
}();
//Uncaught SyntaxError: Duplicate parameter name not allowed in this context

正常模式下,如果函數有多個重名的參數,可以用arguments[i]讀取。嚴格模式下,這屬於語法錯誤。

  

7、嚴格模式下,禁止八進制字面量 

在普通模式下:

!function() {
    console.log(0123);//83
}();

普通模式下可以識別八進制數

在嚴格模式下:

!function() {
    'use strict';
    console.log(0123);//Uncaught SyntaxError: Octal literals are not allowed in strict mode.
}();

會報錯,SyntaxError錯誤

  

8、嚴格模式下,eval, arguments變為關鍵字,不能作為變量、函數名

在普通模式下:

!function() {
    function eval(){}
    console.log(eval);//function eval(){}
}();

在嚴格模式下:

!function() {
    'use strict';
    function eval(){}//Uncaught SyntaxError: Unexpected eval or arguments in strict mode
}();

 

9、嚴格模式下,eval獨立作用域

在普通模式下:

!function() {
    eval('var evalVal = 2;');
    console.log(typeof evalVal);//number
}();

在嚴格模式下:

!function() {
    'use strict';
    eval('var evalVal = 2;');
    console.log(typeof evalVal);//undefined
}();

在嚴格模式下,eval中的代碼不能創建eval所在作用域下的變量、函數。而是為eval單獨創建一個作用域,並在eval返回時丟棄。

正常模式下,Javascript語言有兩種變量作用域(scope):全局作用域和函數作用域。嚴格模式創設了第三種作用域:eval作用域。
正常模式下,eval語句的作用域,取決於它處於全局作用域,還是處於函數作用域。嚴格模式下,eval語句本身就是一個作用域,不再能夠生成全局變量了,它所生成的變量只能用於eval內部。

 

10、嚴格模式下,禁止this關鍵字指向全局對象

在普通模式下:

 !function f(){
    console.log(this);//window
    console.log(!this);//false
  }();

返回false,因為"this"指向全局對象,"!this"就是false

在嚴格模式下:

    !function f(){ 
    "use strict";
    console.log(this);//undefined
    console.log(!this);//true
  }();

 返回true,因為嚴格模式下,this的值為undefined,所以"!this"為true。

使用構造函數時,如果忘了加new,this不再指向全局對象,而是報錯。

    function f(){
    "use strict";
    this.a = 1;//Uncaught TypeError: Cannot set property 'a' of undefined
  };
  f();// 報錯,this未定義

 

11、嚴格模式下,arguments.caller, arguments.callee被禁用

    function f1(){
    "use strict";
    f1.caller; // 報錯
    f1.arguments; // 報錯
  }
  f1();
//Uncaught TypeError: 'caller' and 'arguments' are restricted function properties and cannot be accessed in this context.

 

總結:

不允許用with

所有變量必須聲明, 賦值給為聲明的變量報錯,而不是隱式創建全局變量。

eval中的代碼不能創建eval所在作用域下的變量、函數。而是為eval單獨創建一個作用域,並在eval返回時丟棄。

函數中得特殊對象arguments是靜態副本,而不像非嚴格模式那樣,修改arguments或修改參數變量會相互影響。

刪除configurable=false的屬性時報錯,而不是忽略

禁止八進制字面量,如010 (八進制的8)

eval, arguments變為關鍵字,不可作為變量名、函數名等

一般函數調用時(不是對象的方法調用,也不使用apply/call/bind等修改this)this指向null,而不是全局對象。

若使用apply/call,當傳入null或undefined時,this將指向null或undefined,而不是全局對象。

試圖修改不可寫屬性(writable=false),在不可擴展的對象上添加屬性時報TypeError,而不是忽略。

arguments.caller, arguments.callee被禁用

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM