浅谈ECMAScript 5 严格模式(Strict Mode)

自ECMAScript 5开始,增加了一个严格模式(Strict Mode)的新特性。
ECMAScript 5虽然可以跟前一版的ECMAScript 3相容(ECMAScript 4已废弃) ,
但是,当我们宣告为”Strict Mode”后,那些ECMAScript 5不再建议使用的ECMAScript 3的旧语法会被全面禁止。一旦出现,便会出现错误或抛出异常(Exception)。

Strict Mode 的宣告方式有两种:
若要在全域范围内宣告使用Strict Mode,只需在程式码的第一行加上下面叙述,如:

"use strict"

也可以在指定的函数内宣告使用Strict Mode,在函数的第一行加上下面叙述,如:

// Non-strict code...
function  func_UseStrictMode() {
  "use strict" ;
  // ... your code ...
}


再来简单介绍一下Strict Mode 与非Strict Mode 的差异:
1、变数:
以往我们在使用变数的时候不一定要先宣告(若直接使用未宣告的变数会自动变成全域变数,hold不住变数范围,oh~ No Fashion! ),但在Strict Mode下,变数使用前必须要先用var宣告后才能拿来用,否则会出现错误。

"use strict" ;

try  {
    i = 1;
}
catch  (err) {
    alert(err); // throw exception !
}

另外,在Strict Mode下删除全域变数、函数,或是函数内的参数都会被认为是错误的语法。如下:

"use strict" ;

var  i = 1;
var  myfunc = function  () { };
delete  i;       // Error !
delete  myfunc; // Error !

function  myfunc2(arg) {
    delete  arg; // Error !
}

2、属性:
在定义物件的属性时,属性名称不可重复,同一个物件内不能重复定义相同属性,否则会出现异常:

"use strict" ;

{
    foo: true ,
    foo: false ;   // Error
}

3、函数与参数:
在Strict Mode下,函数的参数(arguments)不能有相同名称的变数,如下:

function  func1(arg1, arg2) { }   // OK
function  func2(arg, arg) { }   // Error

同时,函数的arguments属性在Strict Mode下也是唯读的:

"use strict" ;

function  func(arg) {
    arguments = [ "..." ]; // not allow, Error.
}

另外,对arguments.caller 和arguments.callee 的存取会出现错误。

"use strict" ;

function  test(){
  function  inner(){
    // Don't exist, either
    test.arguments = ...; // Error
    inner.caller = ...; // Error
  }
}

因此,任何需要用到的匿名函数都必须先命名,例如:

setTimeout( function  later(){
  // do stuff...
  setTimeout( later, 1000 );
}, 1000 );

最后,当使用null或者undefined作为Function.prototype.call或Function.prototype.apply方法的第一个参数时,函数内部的this将会指向global object。
而Strict mode将会阻止其执行并抛出异常:

( function (){ ... }).call( null  ); // Exception

4、eval:
eval是保留的关键字,不能作为变数名、函数名、物件的属性,甚至是变数都不行。所以,以下的程式码全都是错误的:

// All generate errors...
obj.eval = ...
obj.foo = eval;
var  eval = ...;
for  ( var  eval in  ... ) {}
function  eval(){}
function  test(eval){}
function (eval){}
new  Function( "eval" )

另外,在Strict mode 透过eval 引入的变数也会无效,如下:

eval( "var a = false;" );
print( typeof  a );   // undefined.

5、with() { }:
在Strict mode下没有这个东西了,如果使用的话会被认为语法错误。

其他:
在Strict mode下,不再支援8进位数字。实际在Firefox 8测试的结果,会出现”octal literals and octal escape sequences are deprecated”的错误:

"use strict"
var j=010;
console.log(j);//octal literals and octal escape sequences are deprecated

在非Strict mode 下,010 则是会alert 出8 这个数字。

发表评论

电子邮件地址不会被公开。 必填项已用 * 标注

*