请解释严格模式 ('use strict') 的作用和特点。

推荐答案

严格模式 ('use strict') 是 JavaScript 中的一种特殊的执行模式,它对 JavaScript 语法和行为施加了更严格的约束。主要作用是:

  1. 消除 JavaScript 语法的一些不合理、不严谨之处,减少怪异行为,使得代码更规范,更易于调试和维护。
  2. 提高代码的安全性,例如禁止使用 with 语句和删除变量等操作。
  3. 为未来的 JavaScript 版本做铺垫,部分在严格模式下报错的行为,未来可能被标准化。

主要特点包括:

  • 必须声明变量: 变量必须先声明再使用,否则会抛出 ReferenceError
  • 禁止使用 with 语句: with 语句在严格模式下会报错,因为它会造成作用域混乱。
  • 禁止函数参数重名: 如果函数参数存在重名,严格模式会报错。
  • 禁止 delete 不可删除的属性: 删除变量、函数或者 arguments,都会报错。
  • this 指向问题: 在全局作用域下的函数中,this 指向 undefined,而不是 window(非严格模式)。
  • 禁止使用八进制数字字面量: 严格模式不允许使用 010 这种形式的八进制数字字面量。
  • eval() 作用域限制: 在严格模式下,eval() 创建的变量不会被引入到包含 eval() 的作用域中。
  • 不允许使用 arguments.calleearguments.caller 这两者在严格模式下被禁用。
  • 保留关键字: 将一些保留关键字 (如 implements, interface, let, package, private, protected, public, static, yield) 作为变量名会报错。

本题详细解读

什么是严格模式?

严格模式,顾名思义,就是让 JavaScript 的执行变得更加严格的一种模式。它并不是一种新的语法,而是在 JavaScript 代码的开头通过添加字符串 'use strict'"use strict" 来激活的一种特殊模式。它可以在全局作用域或函数作用域中使用。

为什么需要严格模式?

早期的 JavaScript 为了兼容性和易用性,允许很多不严谨的语法和行为。这在一定程度上降低了开发难度,但也导致了一些问题:

  • 隐式全局变量: 如果你忘记声明一个变量,JavaScript 会默认将其作为全局变量,这容易造成命名冲突和意外的副作用。
  • with 语句: with 语句可以临时改变作用域,这使得代码难以理解和维护。
  • this 指向不明确: 在一些情况下,this 的指向并不符合预期,可能会导致错误。
  • 一些历史遗留问题: 例如,允许使用八进制数字字面量,这使得代码看起来不直观。

为了解决这些问题,并让 JavaScript 变得更加规范,引入了严格模式。

如何使用严格模式?

在 JavaScript 代码的开头添加 'use strict'"use strict" 来激活严格模式。

  • 全局严格模式: 在脚本的开头添加,整个脚本的代码都会以严格模式执行。

  • 函数严格模式: 在函数体内部的开头添加,只有该函数内的代码会以严格模式执行。

严格模式的主要特点详解

  1. 必须声明变量

    在非严格模式下,如果一个变量没有被声明就直接赋值,那么 JavaScript 会将其隐式声明为全局变量。在严格模式下,这样做会抛出 ReferenceError

  2. 禁止使用 with 语句

    with 语句可以扩展作用域链,但会带来作用域不确定性的问题。严格模式下禁止使用 with 语句,避免作用域混乱。

  3. 禁止函数参数重名

    在非严格模式下,如果函数参数重名,后面的参数会覆盖前面的参数。在严格模式下,函数参数不能重名。

  4. 禁止 delete 不可删除的属性

    在非严格模式下,delete 操作符删除不可删除的属性(例如变量)不会报错,但会返回 false。在严格模式下,删除变量、函数或者 arguments 会报错。

  5. this 指向问题

    在非严格模式下,全局函数调用时,this 指向 window (浏览器环境) 或全局对象。在严格模式下,全局函数调用时,this 指向 undefined。这使得开发者必须明确 this 的指向,避免错误。

  6. 禁止使用八进制数字字面量

    在非严格模式下,以 0 开头的数字字面量被认为是八进制数,例如 010 表示十进制的 8。严格模式禁止这种写法。

  7. eval() 作用域限制

    在非严格模式下, eval() 执行的代码可以修改外部作用域的变量。在严格模式下,eval() 创建的变量会被限制在 eval() 内部的作用域中,不会影响外部作用域。

  1. 不允许使用 arguments.calleearguments.caller

arguments.callee 指向当前正在执行的函数, arguments.caller 指向调用当前函数的函数。 这两者在严格模式下被禁用,因为它们在某些场景下会影响代码性能和安全性。

-- -------------------- ---- -------
 ---- --------
 -------- ----- -
     -- ---------- --------- --------- --- ----------- ---------- --- --- -- -------- -- ------ ---- --------- -- --- --------- ------- --- ----- -- ----
    -----------------
    -----------------
 -
 ------
 ---

--  ---------

 ------------------------ ------------- ------------ ------ ---------- ---------- ------------ --------- --------- ------- --
 -------------
 ---- --------
 --- --------- - --- -- ------------ ---------- ------ ---- -------- ----
 ---

--- -------

-   ---------- ----------------------------
-   ---------- -------------------------------
-   ----------- ---------------------------
-   ------ ---------- -------- ------------------ ---------- ----------

--- -------

-   ----------- --------------------------
-   ----------- ----------------------------

--------------------- ---------- ------------
纠错
反馈