Javascript的严格模式

来源:互联网 发布:网络海报设计 编辑:程序博客网 时间:2024/05/20 01:47

在严格模式下,能够在函数内部选择进行较为严格的全局或局部的错误条件检测。使用严格模式的好处是可以提早知道代码中存在的错误,即使捕获一些可能导致编程uowu的ECMAScript行为。
  理解严格模式的规范非常重要,ECMAScript的下一个版本将以严格模式为基础指定。支持严格模式的浏览器包括IE10+,Firefox4+, Safari5.1+和Chrome。

选择使用

  要选择进入严格模式,可以使用严格模式的编译指示,实际上就是一个不会赋给任何变量的字符串:
  use strict;
  在老版本的浏览器里,会把它当做一行普通的字符串,加以葫芦。
  如果在全局作用域中(函数外部)给出这个编译知识,则整个脚本都将使用严格模式。换句话说,如果把带有这个编译指示的脚本放到其他文件中,则该文件中的Javascript代码将处于严格模式下。
  也可以只在函数中打开严格模式,就像下面这样:

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

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

变量

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

// 未声明变量// 非严格模式:创建全局变量// 严格模式:抛出错误message = "hello wenzi";

  即使message前面没有var关键字,即使没有将它定义为某个全局对象的属性,也能将message为全局变量。但在严格模式下,如果给一个没有声明的变量赋值,那代码在执行时就会抛出错误。
  其实不能对变量调用delete操作符。非严格模式允许这样操作,单户静默失败(返回false),而在严格模式下,删除变量也会导致错误。

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

  严格模式下对变量名也有限制。特别地,不能使用implementsinterfaceprotectedpublicstaticyield作为变量名。这些都是保留字,将来的ES版本中可能会使用到他们。在严格模式,用以上的标识符作为变量会导致语法错误。

对象

  在严格模式下操作对象比在非严格模式下更容易导致错误。一般来说,非严格模式下会静默失败的情形,在严格模式下就会抛出错误。因此在开发中使用严格模式更能发现错误。
  在下列情形下操作对象的属性会导致错误: + 为只读属性进行赋值; + 为不可配置的属性使用delete操作符; + 为不可扩展的对象添加谁能够   使用对象的另一个限制与通过对象字面量声明对象有关。在使用对象字面量时,属性名必须唯一。例如:

// 重名属性// 非严格模式:没有错误,以第二个属性为准// 严格模式:抛出语法错误var student = {    name : 'wenzi',    name : 'bing'}

  这里的对象student有两个属性,都叫name。在非严格模式下,student对象的name属性值是第二个,而在严格模式下,这样的代码会导致语法错误。

函数

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

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

  在非严格模式下,这个函数声明不会抛出错误。通过参数名只能访问第二个参数,要访问第一个参数必须通过arguments对象。
  在严格模式下,arguments对象的行为也有所不同,在非严格模式下,修改明明参数的值也会反应到arguments对象中,而严格模式下这两个值是完全独立的。如:

// 修改命名参数的值// 非严格模式:修改会反应到arguments中// 严格模式:修改不会反应到arguments中function doSomething(value){    value = 7;    console.log(value, arguments[0]);    // 非严格模式下,输出:7, 7    // 严格模式下,输出:7, 10}doSomething(10);

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

// 访问arguments.callee// 非严格模式:正常// 严格模式:抛出错误function factorial(num){    if(num<=) return 1;    return num*arguments.callee(num-1);}var result = factorial(4);

  与变量类似,严格模式对函数名也作出了限制,不允许使用implementsinterfaceprotectedpublic,staticyield作为函数名。
  对函数的最后一点限制,就是只能在脚本的顶级和在函数内部声明函数。而在if语句中声明函数与导致语法错误:

if(true){    function doSomething(){        // ...    }}

  在非严格模式下,以上代码在所有的浏览器上都能运行;而严格模式下会导致语法错误。
###eval() 
  饱受诟病的eval()在严格模式下也得到了提升。最大的变化就是它在包含上下文中不再创建变量或函数。例如:

// 使用eval()创建变量// 非严格模式:弹出对话框显示10// 严格模式:抛出错误function doSomething(){    eval("x=10");    alert(x);}

  如果在非严格模式下,以上代码在函数中会创建一个局部变量x,然后alert(),还会显示该变量的值。但在严格模式下,在doSomething()函数调用eval()不会创建变量x,因此调用alert()会导致抛出错误,因为x没有定义。
  可以在eval()中声明变量和函数,但这些变量或函数只能在被求值的特殊作用域中有效,随后就将被销毁。

其他变化

  严格模式还有其他一些变化,希望能够注意。首先是抛弃了with语句。非严格模式下的with能够改变解析变支付的路径,但在严格模式下,with被简化掉了。因此,在严格模式使用with会导致语法错误。

// with语句// 非严格模式:允许// 严格模式:抛出错误with(location){    alert(href);}

  严格模式下也去掉了Javascript中的八进制字面量。以0开头的八进制字面量经常会导致很多错误。在严格模式下,八进制字面量已经成为了无效的语法了。

// 使用八进制字面量// 非严格模式:值为8// 严格模式:抛出语法错误var value = 010;

  ES5也修改了严格模式下parseInt()的行为。如今,八进制字面量在严格模式下会被当做以0开头的十进制字面量。例如:

// 使用parseInt()解析八进制字面量// 非严格模式:值为0// 严格模式:值为10var value = parseInt("010");

by 蚊子 fromhttp://www.xiabingbao.com

本文地址:http://www.xiabingbao.com/javascript/2015/02/14/javascript-strict/

0 0