首页 > 代码库 > Javascript 严格模式详解(上)

Javascript 严格模式详解(上)

  ECMAScript 5最早引进了“严格模式”(strict mode)的概念。通过严格模式,可以在函数内部选择进行较为严格的全局或局部的错误条件检测。使用严格模式的好处是可以提早知道代码中存在的错误,及时捕获一些可能导致变成错误的ECMAScript行为。支持严格模式的浏览器包括IE 10+,Firefox 4+,Safari 5.1+和Chrome。

 1.   选择使用

   要进入严格模式,可以使用严格模式的编译指示(pragma)

“use strict”;

 

  如果是在全局作用域中(函数外部)给出这个编译指示,则整个脚本都将使用严格模式。

  也可是只在函数中打开严格模式,就像下面这样:

function doSomething(){       "use strict";     //其他代码}

 

  如果你没有控制页面中所有脚本的权利,则只需要在测试的特定函数中开启严格模式。

  2.   变量

  在严格模式下,什么时候创建变量以及怎么创建变量都是有限制的。首先,不允许意外创建全局变量。在非严格模式下,可以像那这样创建全局变量:

//未声明变量//非严格模式:创建全局变量//严格模式:抛出ReferenceErrormessage="Hello World!";

 

  即使message前面没有var关键字,即使没有将它定义为某个全局对象的属性,也能将message创建为全局变量。但在严格模式下,如果给一个没有声明的变量赋值,代码在执行时就会抛出ReferenceError。

  其次,不能对变量调用delete操作符。非严格模式允许这样操作,但会静默失败。而在严格模式下,删除变量也会导致错误。

//删除变量//非严格模式:静默失败//严格模式:抛出ReferenceErrorvar color="red";delete color;

 

  严格模式下对变量名也有限制。特别的,不能使用implements,interface,let,package,private,protected,public,static和yield作为变量名。在严格模式下,用以上标识符作为变量名会导致语法错误。

 3.对象

  在严格模式下操作对象比在非严格模式下更容易导致错误。一般说来,非严格模式下会静默失败的情形,在严格模式下就会抛出错误。因此,在开发中使用严格模式会加大早发现错误的可能性。

  在下列情形下操作对象的属性会导致错误:

  • 为只读属性赋值会抛出TypeError;
  • 对不可配置的(nonconfigurable)的属性使用delete操作符会抛出TypeError;
  •  为不可扩展的(nonextensible)的对象添加属性会抛出TypeError。

   使用对象的另一个限制与通过对象字面量声明对象有关。在使用对象字面量时,属性名必须唯一。

例如:

//重名属性//非严格模式:没有错误,以第二个属性为准//严格模式:抛出语法错误var person={                name:"Nicholas",                name:"Greg"           };

 

   4.    函数

   首先,严格模式要求命名函数的参数必须唯一。以下面函数为例:

//重名参数//非严格模式:没有错误,只能访问第二个参数//严格模式:抛出语法错误function sum(num,num){                         //do sonmething}

 

    在非严格模式下,这个函数声明不会抛出错误。通过参数名只能访问第二个参数,要访问第一个参数必须通过arguments对象。

    在严格模式下,arguments对象的行为也有所不同,在非严格模式下,修改命名参数的值也会反映到argument对象中,而严格模式下这两个值是完全独立的。例如:

//修改命名参数的值//非严格模式:修改会反映到argument中//严格模式:修改不会反映到argument中function showValue(value){       value="Foo";       alert(value);             //"Foo"       alert(argument[0]);  //非严格模式:"Foo"                                    //严格模式:"Hi"}showValue("Hi");

   另一个变化是淘汰了arguments.callee和arguments.caller。在非严格模式下,这两个属性一个引用函数本身,一个引用调用函数。而在严格模式下,访问哪个属性都会抛出TypeError。例如:

//访问arguments.callee//非严格模式:没有问题//严格模式:抛出TypeErrorfunction factorial(num){     if(num<=1){              return;     }else{              return num*arguments.callee(num-1)     }}var result=factorial(5);

   类似的,尝试读写函数的caller属性,也会导致抛出TypeError。所以,对于上面的例子而言,访问factorial.caller也会抛出错误。

   与变量类似,严格模式对函数名也做出了限制,不允许用implements,interface,let,package,private,protected,public,static和yield作为函数名。

   对函数的最后一点限制,就是只能在脚本的顶级和在函数内部声明函数,也就是说,在if语句中声明函数会导致语法错误:

//在if语句中声明函数//非严格模式:将函数提升到if语句外//严格模式:抛出语法错误if(true){     function dosomething(){               //.....     }}

  在非严格模式下,以上代码能在所有浏览器中运行,但在严格模式下会导致语法错误。

 

Javascript 严格模式详解(上)