5.4.5. 严格模式
5.4.5.1. 简介
在ES5中,除了正常的运行模式之外,添加了严格模式(strict mode),这种模式使得代码显式地脱离“马虎模式/稀松模式/懒散模式“(sloppy)模式在更严格的条件下运行。严格模式不仅仅是一个子集:它的产生是为了形成与正常代码不同的语义。
引入严格模式的目的主要是:
- 通过抛出错误来消除了一些原有静默错误
- 消除JavaScript语法的一些不合理、不严谨之处,减少一些怪异行为
- 消除代码运行的一些不安全之处,保证代码运行的安全
- 修复了一些导致 JavaScript引擎难以执行优化的缺陷,提高编译器效率,增加运行速度
- 禁用了在ECMAScript的未来版本中可能会定义的一些语法,为未来新版本的JavaScript做铺垫
5.4.5.2. 调用
严格模式使用 "use strict";
字符串开启。对整个脚本文件而言,可以将 "use strict"
放在脚本文件的第一行使整个脚本以严格模式运行。如果这行语句不在第一行则不会生效,会以正常模式运行。
对单个函数而言,将 "use strict"
放在函数体的第一行,则整个函数以严格模式运行。
5.4.5.3. 行为改变
在严格模式中,主要有以下的行为更改:
5.4.5.3.1. 全局变量显式声明
在正常模式中,如果一个变量没有声明就赋值,默认是全局变量。严格模式禁止这种用法,全局变量必须显式声明。
- "use strict";
- for(i = 0; i < 2; i++) { // ReferenceError: i is not defined
- }
5.4.5.3.2. 禁止使用with语句
with语句无法在编译时就确定,属性到底归属哪个对象,这会影响编译效率,所以在严格模式中被禁止。
5.4.5.3.3. 创设eval作用域
正常模式下,eval语句的作用域,取决于它处于全局作用域,还是处于函数作用域。严格模式下,eval语句本身就是一个作用域,不再能够生成全局变量了,它所生成的变量只能用于eval内部。
5.4.5.3.4. 禁止删除变量
严格模式下无法删除变量。只有configurable设置为true的对象属性,才能被删除。
5.4.5.3.5. 显式报错
正常模式下一些错误只会默默地失败,但是严格模式下将会报错,包括以下几种场景:
- 对一个对象的只读属性进行赋值
- 对一个使用getter方法读取的属性进行赋值
- 对禁止扩展的对象添加新属性
- 删除一个不可删除的属性
5.4.5.3.6. 语法错误
严格模式新增了一些语法错误,包括:
- 对象不能有重名的属性
- 函数不能有重名的参数
- 禁止八进制表示法
- 函数必须声明在顶层
- 新增保留字
- class
- enum
- export
- extends
- import
- super
5.4.5.3.7. 安全增强
- 禁止this关键字指向全局对象
- 禁止在函数内部遍历调用栈
5.4.5.3.8. 限制arguments对象
- 不允许对arguments赋值
- arguments不再追踪参数的变化
- 禁止使用arguments.callee