首页 > 代码库 > 原生JS:严格模式详解

原生JS:严格模式详解

严格模式

本文参考MDN做的详细整理,方便大家参考[MDN](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript)

设计目的

设立”严格模式“的目的,主要有以下几个。

  • 明确禁止一些不合理、不严谨的语法,减少JavaScript的一些怪异行为。
  • 增加更多报错的场合,消除代码运行的一些不安全之处,保证代码运行的安全。
  • 提高编译器效率,增加运行速度。
  • 为未来新版本的JavaScript做好铺垫。

“严格模式”体现了JavaScript更合理、更安全、更严谨的发展方向

开启严格模式

  • 严格模式可以应用到整个script标签或个别函数中。
  • 不要在封闭大括弧( {} )内这样做,在这样的上下文中这么做是没有效果的
  • 在eval 代码,Function 代码,事件处理属性,传入 setTimeout方法的字符串和包含整个脚本的块中开启严格模式会如预期一样工作。 

为某个script标签开启严格模式:需要在所有语句之前放一个特定语句 "use strict"; (或 ‘use strict‘;)老版本的浏览器(IE10以下)会把它当作一行普通字符串,加以忽略。

针对整个脚本文件

use strict放在脚本文件的第一行,则整个脚本都将以“严格模式”运行。如果这行语句不在第一行就无效,整个脚本会以“正常模式”运行。(严格地说,只要前面不是产生实际运行结果的语句,use strict可以不在第一行,比如直接跟在一个空的分号后面,或者跟在注释后面。)

  • 合并均为严格模式的脚本或均为非严格模式的都没问题,只有在合并严格模式与非严格模式有可能有问题。建议按一个个函数去开启严格模式。
  • 您也可以将整个脚本的内容用一个立即执行的匿名函数包括起来,然后在这个函数中使用严格模式。

 为某个函数开启严格模式

同样的,要给某个函数开启严格模式,得把 "use strict";  (或 ‘use strict‘; )声明放在函数体所有语句之前

将拼写错转成异常:

  • 严格模式下无法再意外创建全局变量,即所有变量必须用var显式声明
  • 严格模式下任何在正常模式下引起静默失败的赋值操作都会抛出异常
  • 在严格模式下, 试图删除不可删除的属性时会抛出异常(之前这种操作不会产生任何效果)
  • 在严格模式下要求一个对象内的所有属性名在对象内必须唯一,重名属性被认为是语法错误
  • 严格模式要求函数的参数名唯一,重名参数被认为是语法错误
  • 严格模式禁止八进制数字语法(以零0开头的八进制语法: 0644 === 420 还有 "\045" === "%"),八进制语法将会引起语法错误(整数第一位为0,将报错)

简化变量的使用:

  • 严格模式禁用 with,严格模式下, 使用 with 会引起语法错误
  • 严格模式下的 eval 不在为上层范围(包围eval代码块的范围)引入新变量,在严格模式下 eval 仅仅为被运行的代码创建变量。当直接调用eval(str)时,若eval(str)在严格模式下,则str代码也在严格模式下执行;当间接调用eval(str)时,str代码必须自行开启严格模式。
  • 严格模式禁止删除变量,只能删除对象的属性,否则引起语法错误

严格模式让argumentseval少了一些奇怪的行为:

  • 名称 eval 和 arguments 不能通过程序语法被绑定(be bound)或赋值.
  • 严格模式下,eva、arguments将作为保留字,使用eval或者arguments作为标识名,将会报错
  • 严格模式下,函数内部改变参数与arguments的联系被切断了,两者不再存在联动关系。

增强的安全措施

  • 禁止this关键字指向全局对象(undefined)。这种限制对于构造函数尤其有用。使用构造函数时,有时忘了加new,这时this不再指向全局对象,而是报错
  • 函数内部不得使用fn.callerfn.arguments,否则会报错。这意味着不能在函数内部得到调用栈了。
  • 禁止使用arguments.callee、arguments.caller

静态绑定

  • 严格模式下,禁止使用with语句,使用with语句将报错。因为with语句无法在编译时就确定,某个属性到底归属哪个对象,从而影响了编译效果
  • 严格模式创设了第三种作用域:eval作用域。eval语句本身就是一个作用域,不再能够在其所运行的作用域创设新的变量了,也就是说,eval所生成的变量只能用于eval内部。

向下一个版本的JavaScript过渡

  • JavaScript的新版本ES6会引入“块级作用域”。为了与新版本接轨,严格模式只允许在全局作用域或函数作用域声明函数。也就是说,不允许在非函数的代码块内声明函数。如if语句内、for循环体内
  • 为了向将来JavaScript的新版本过渡,严格模式新增了一些保留字:implements, interface, let, package, private, protected, public, static, yield。

原生JS:严格模式详解