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被禁用

原文地址:https://www.cnblogs.com/aimee2004/p/5161285.html