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