JavaScript 严格模式

##1. 严格模式

‘Use Strict’ 特性是在2009年12月发布的ECMAScript 5中引入的,允许将一段程序或者方法加入严格语法检查的上下文中。其目地是通过使用严格模式,避免JavaScript中那些模糊杂乱,不安全的使用与错误,比如使用没有定义的变量,比如重复定义,比如修改只读属性,比如this访问全局变量等。这些编程中出现的错误以前会被Javascript Engine偷偷的吃掉,从而发生一些神奇的事情。而引入严格模式以后,这些错误则会通过异常,语法错误等方式被显示的暴露出来,从而帮助程序员更好的调试,从而加强Javascript使用规范与最佳实践,带来整洁的代码。同时也可以帮助Javascript Engine更好的进行优化。

##2. 浏览器支持

目前大多数主流的浏览器最新版都支持严格模式,包括IE10+,Opera12。CanIUse提供了不同浏览器版本对严格模式的支持信息,kangx’s strict mode support则可以验证当前浏览器对严格模式具体特性的支持。

##3. 如何使用
在javascript 文件或代码块中加入 ‘use strict’,适用范围可以是全局的,也可以是某一个方法体内部。

  • 文件全局范围

在javascript文件的第一行加入 ‘use strict’,这个文件的所有javascript都会使用严格模式进行语法检查。

apply Strcit Mode
1
2
3
4
5
'use strict';
function(){
// in strict mode
}
//in strict mode
  • 方法范围

在方法体的第一行加入’use strict’。

apply Strcit Mode
1
2
3
4
5
function() {
'use strict';
//in strict mode
}
// not in strict mode

use strict一定是在文件或者方法的第一行,并且有效的第一行。下面代码中将不会启用严格模式。

apply Strcit Mode
1
2
3
4
5
function() {
var test = 'test';
'use strict';
//not in strict mode;
}

推荐第二种方式而不推荐在全局使用。因为目前并不是所有的Javascript都支持严格模式,所以为了保证与引入严格模式之前的Javascript代码及相关类库的兼容,建议只在需要启用的地方使用,也即是第二种方式;二是多个Javascript文件合并的情况,如果采取全局方式,合并后回导致 use strict不在第一行,则严格模式不会被启用*

##4. 严格模式检查的内容

1) 变量在使用前必须声明。

在正常模式中,如果一个变量没有声明就赋值,默认是全局变量。严格模式禁止这种用法,变量必须显式声明才能使用,这样可以避免在非严格模式下发生的一些神奇的事情,诸如不同上下文出现的重复变量。

use undefined var
1
2
'use strict';
test = 'abc'; //throw error

2) 不可扩展属性的对象不能添加新的属性

ES5引入了两个方法修改和验证对象的可扩展性。

extend non-Extensible object
1
2
Object.preventExtensions( obj )
Object.isExtensible( obj )

在非严格模式下默默的吃掉的错误在严格模式下会显示的报错。

extend non-Extensible object
1
2
3
4
var obj = {name: 'hanse'};
Object.preventExtensions(obj);

obj.age = "3"; //throw error

3) 对象不能具有同样名称的属性

no duplicate property
1
2
3
4
5
'use strict'
var obj = {
'name': 'abcd',
'name': 'abcd'
}; //throw error

4) 函数不允许重复名字的参数

no duplicate param
1
2
3
'use strict';
function(name, name){ //throw error
}

5) 对于number对象赋值,不再使用八进制

apply Strcit Mode
1
2
3
4
'use strict'
var total = 010; //throw error: Octal literals are not allowed in strict mode.
var count = \010; //throw syntax error

6) delete 不能用于参数函数变量或者其他属性。

严格模式下无法删除变量。只有configurable设置为true的对象属性,才能被删除。

7) 引入eval作用域

eval代码块中引入的变量只在内部scope有效,外部使用会抛错。

eval代码块
1
2
3
4
5
'use strict'
var eval = “eval”; //throw error

eval("var total = 1;")
total = 10; // throw error

8) with 禁止使用

9) arguments的限制

严格模式中,不能对arguments进行赋值,它作为方法参数的一个复本,不在与参数引用同一个对象;同时禁止使用arguments.callee。

arguments
1
2
3
4
5
6
7
'use strict'
function testArgs(oneArg) {
arguments[0] = 20;
}

testArgs([1,2,3]); //oneArg保持不变,arguments = 20;

10) 禁止this指向全局对象

在非严格模式下,如果this没有定义会指向全局对象;在严格模式引入后禁止this指向全局对象,二是返回undefined.

this
1
2
3
4
5
6
7
8
'use strict'

function calculator(input) {
this.total = input; // throw error
}

calculator(1);

11) 未来保留的关键字

在严格模式下遇到这些关键字均会抛出异常。

  • implements
  • private
  • protected
  • public
  • static
  • interface
  • let
  • package
  • yield

#####参考

  1. http://ejohn.org/blog/ecmascript-5-strict-mode-json-and-more/
  2. http://www.ruanyifeng.com/blog/2013/01/javascript_strict_mode.html
  3. http://msdn.microsoft.com/zh-cn/library/br230269(v=vs.94).aspx
Share Comments