您的位置:首页 > Web前端 > JavaScript

javascript 严格模式

2016-03-03 15:43 489 查看
严格模式是一种特殊的执行模式,它修复了部分语言上的不足,提供更强的错误检查,并增强安全性。

一、如何使用严格模式?

可以在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被禁用
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: