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