ECMAScript 5中引入了严格模式(strict mode),相同的代码在严格模型下有时会比普通模式下执行的更快。在严格模式下,执行引擎会对JavaScript进行更加严格的语法检查,一些在普通模式下的静默错误会在严格模式下抛出异常。
在语义上严格模式与普通模式并不完全一致,其主要表现在以下几个方面:
使用严格模式时应该保证执行环境支持严格模型,并对相关代码进行充分测试。严格模式可以与非严格模式共存,所以可以选择性对代码加入严格模式。
启用严格模型,只要在代码中加入”use strict”;或’use strict’;即可。我们可以为整个script标签或一个.js文件全部开启严格模式,也可以为某一个函数单独开启严格模式。
在一个script标签或一个.js文件的顶部加入”use strict”;或’use strict’;,整个标签或文件就会运行在严格模式下:
严格模式与非严格模式的模式的代码并不能合并使用,这时我们可以将使用严格式的代码封装到一个函数中,并对这个函数开启严格模式。对函数使用严格模式,同样在顶部加入”use strict”;或’use strict’;即可:
JavaScript会对错误进行静默处理,有时候会给本来错误操作进行不报错处理,这可能会解决当前问题,但可能会给程序留下一些隐患。严格模式对JavaScript进行了非严格的语法检查,原本不报错的一些操作在严格模式下会抛出错误。
启严格模式(‘use strict’)后,在下面情况下会抛出SyntaxError异常。
当使用delete删除已声明的变量时,会抛出SyntaxError错误:
with语句会导致执行引擎无法进行优化,所以执行速度也会变慢。严格模式禁用with语句,使用时会抛出SyntaxError错误:
在普通模式中,在对象中使用重复的属性名时,只有最后一个属性会起作用。但在严格模式中,会抛出SyntaxError异常:
在普通模式中,重复的函数参数名与重复的对象属性名处理方式类似,后面的参数会覆盖前面的同名参数。但在严格模式中,会抛出SyntaxError异常:
eval是JavaScript中的一个全局对象;arguments表示JavaScript的函数参数对象。在普通模式中eval和arguments都可作为变量名或函数名,但在严格模式中会抛出SyntaxError异常:
严 格模式对可能在ECMAScript 6中或未来版本的语言规范中使用的关键字,如:implements、interface、let、package、private、 protected、public、static、yield。使用这些关键字作为变量名或函数名,严格模式可能会抛出SyntaxError异常:
在ECMAScript规范中并没有关于八进制语法的定义,但以0开头的八进制语法确得到了浏览器的广泛支持,如:0644 === 420、”/045″ === “%”。但在严格模式中使用八进制语法可能会抛出SyntaxError异常:
严格模式下,只能脚本级别或函数级别声名函数。
“不能ECMAScript预留关键字”及“禁止块级的函数声明”为未来版本的ECMAScript可能会引入的新语法提供了保护,扫除了语言未来发展中的一些障碍。
JavaScript在某些上下文情况下会对失败做静默处理,但在严格模式中同样情况下会抛出错误。
普通模式下,JavaScript会对未赋值的错误使用全局变量,而在严格模式下将抛出ReferenceError异常:
普通模式下,对不合法的对象属性操作会进行静默失败处理。如:对只读属性赋值、给不可写属性赋值、给不可扩展对象添加属性、删除不可删除的属性时,操作不会成功但也不没有任何错误提示。在严格模式中,这些操作都会抛出TypeError异常:
严 格模式下,使用以下Arguments对象的:arguments.callee和arguments.caller属性或使用Function对象的 anyFunction.caller和anyFunction.arguments属性时,会产生TypeError异常。
严格模式与普通模式有一些微小的语义差别,了解这些差异可以帮我们写出严格模式更加健壮的代码。
在普通函数中this总会被封将成一个对象,而在严格模式中this不在被封装成对象。如果没有指定其值,那么它的值是’undefined’:
在实际应用中并不推荐使用eval,在严格模式中也不例外。当需要使用eval时应该注意,严格模式中eval不会在当前的作用域内创建新的变量,eval中传入的字符串也会按严格模式进行解析。
正常模式下,函数的参数(形参)值会随arguments对象的变化而变化,反之亦然。而在严格模式下,传递中函数中的值是形参值的拷贝,所以其值不会随arguments的变化而变化。