ECMAScript 5的严格模式是采用具有限制性JavaScript变体的一种方式,从而使代码显示地 脱离“马虎模式/稀松模式/懒散模式“(sloppy)模式。
严格模式对正常的 JavaScript语义做了一些更改。
- 首先,严格模式通过抛出错误来消除了一些原有静默错误。
- 其次,严格模式修复了一些导致 JavaScript引擎难以执行优化的缺陷:有时候,相同的代码,严格模式可以比非严格模式下运行得更快。
- 第三,严格模式禁用了在ECMAScript的未来版本中可能会定义的一些语法。
一. 开启严格模式
为单独js文件开启严格模式
为整个脚本文件开启严格模式, 需要在所有语句之前放一个特定语句 "use strict"; (或 'use strict';)
- 成功开启
"use strict" a = 10; console.log(a);
- 开启失败
a = 10; "use strict" console.log(a);
- 成功开启
为某个函数开启严格模式
同样的,要给某个函数开启严格模式,得把 "use strict"; (或 'use strict'; )声明一字不漏地放在函数体所有语句之前。
function strict(){ // 函数级别严格模式语法 'use strict'; function nested() { return "And so am I!"; } return "Hi! I'm a strict mode function! " + nested(); }
二. 严格模式有哪些不同
严格模式同时改变了语法及运行时行为。变化通常分为这几类:
将问题直接转化为错误(如语法错误或运行时错误),
简化了如何为给定名称的特定变量计算,
简化了 eval 以及 arguments,
将写"安全“JavaScript的步骤变得更简单,
以及改变了预测未来ECMAScript行为的方式。
2.1 拼写错误转成异常
严格模式下无法再意外创建全局变量
严格模式会使以前引起静默失败(silently fail,注:不报错也没有任何效果)的赋值操抛出异常 例如: 给
NaN
赋值.任何在正常模式下引起静默失败的赋值操作 (给不可写属性赋值, 给只读属性(getter-only)赋值赋值, 给不可扩展对象(non-extensible object)的新属性赋值) 都会抛出异常
在严格模式下, 试图删除不可删除的属性时会抛出异常(之前这种操作不会产生任何效果): 例如: 删除函数的
prototype
属性.严格模式要求函数的参数名唯一.
在正常模式下, 最后一个重名参数名会掩盖之前的重名参数. 之前的参数仍然可以通过 arguments[i] 来访问, 还不是完全无法访问. 然而, 这种隐藏毫无意义而且可能是意料之外的 (比如它可能本来是打错了), 所以在严格模式下重名参数被认为是语法错误:
"use strict" function foo(a, a, b){ console.log(a, a, b); }
严格模式禁止八进制数字语法.
ECMAScript并不包含八进制语法, 但所有的浏览器都支持这种以零(0)开头的八进制语法: 0644 === 420 还有 "\045" === "%".
在ECMAScript 6中支持为一个数字加"0o"的前缀来表示八进制数.
有些新手开发者认为数字的前导零没有语法意义, 所以他们会用作对齐措施 — 但其实这会改变数字的意义! 八进制语法很少有用并且可能会错误使用, 所以严格模式下八进制语法会引起语法错误:
"use strict"; sum = 015 + // !!! 语法错误 197 + 142;
- 严格模式禁止设置
primitive
(基本类型)值的属性.不采用严格模式,设置属性将会简单忽略(no-op),采用严格模式,将抛出TypeError错误
2.2 简化变量的使用
禁用
with
的使用.使用
eval
不在为上层函数(或全局变量创建新的变量).严格模式禁止删除声明的变量.
2.3 arguments
变简单
1. 严格模式下`arguments`会保存参数的原始值.
2. 不再支持`arguments.callee`
2.4 不能随意声明函数
严格模式只允许在脚本和函数层面上声明函数.
比如在if, for语句中声明函数会无效.
4. 浏览器的有严格模式
主流浏览器现在实现了严格模式。但是不要盲目的依赖它,因为市场上仍然有大量的浏览器版本只部分支持严格模式或者根本就不支持(比如IE10之前的版本)。严格模式改变了语义。依赖这些改变可能会导致没有实现严格模式的浏览器中出现问题或者错误。谨慎地使用严格模式,通过检测相关代码的功能保证严格模式不出问题。最后,记得在支持或者不支持严格模式的浏览器中测试你的代码。如果你只在不支持严格模式的浏览器中测试,那么在支持的浏览器中就很有可能出问题,反之亦然。