推荐答案
严格模式 ('use strict'
) 是 JavaScript 中的一种特殊的执行模式,它对 JavaScript 语法和行为施加了更严格的约束。主要作用是:
- 消除 JavaScript 语法的一些不合理、不严谨之处,减少怪异行为,使得代码更规范,更易于调试和维护。
- 提高代码的安全性,例如禁止使用
with
语句和删除变量等操作。 - 为未来的 JavaScript 版本做铺垫,部分在严格模式下报错的行为,未来可能被标准化。
主要特点包括:
- 必须声明变量: 变量必须先声明再使用,否则会抛出
ReferenceError
。 - 禁止使用
with
语句:with
语句在严格模式下会报错,因为它会造成作用域混乱。 - 禁止函数参数重名: 如果函数参数存在重名,严格模式会报错。
- 禁止
delete
不可删除的属性: 删除变量、函数或者arguments
,都会报错。 this
指向问题: 在全局作用域下的函数中,this
指向undefined
,而不是window
(非严格模式)。- 禁止使用八进制数字字面量: 严格模式不允许使用
010
这种形式的八进制数字字面量。 eval()
作用域限制: 在严格模式下,eval()
创建的变量不会被引入到包含eval()
的作用域中。- 不允许使用
arguments.callee
和arguments.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"
来激活严格模式。
全局严格模式: 在脚本的开头添加,整个脚本的代码都会以严格模式执行。
'use strict'; // 严格模式下的代码
函数严格模式: 在函数体内部的开头添加,只有该函数内的代码会以严格模式执行。
function myFunction() { 'use strict'; // 严格模式下的代码 }
严格模式的主要特点详解
必须声明变量
在非严格模式下,如果一个变量没有被声明就直接赋值,那么 JavaScript 会将其隐式声明为全局变量。在严格模式下,这样做会抛出
ReferenceError
。'use strict'; x = 10; // ReferenceError: x is not defined var y = 20; // 正确
禁止使用
with
语句with
语句可以扩展作用域链,但会带来作用域不确定性的问题。严格模式下禁止使用with
语句,避免作用域混乱。'use strict'; var obj = { x: 1 }; with (obj) { // SyntaxError: Strict mode code may not include a with statement console.log(x); }
禁止函数参数重名
在非严格模式下,如果函数参数重名,后面的参数会覆盖前面的参数。在严格模式下,函数参数不能重名。
'use strict'; function foo(a, a) { // SyntaxError: Duplicate parameter name not allowed in this context console.log(a); }
禁止
delete
不可删除的属性在非严格模式下,
delete
操作符删除不可删除的属性(例如变量)不会报错,但会返回false
。在严格模式下,删除变量、函数或者arguments
会报错。'use strict'; var x = 10; delete x; // SyntaxError: Delete of an unqualified identifier in strict mode. function foo(){}; delete foo; // SyntaxError: Delete of an unqualified identifier in strict mode.
this
指向问题在非严格模式下,全局函数调用时,
this
指向window
(浏览器环境) 或全局对象。在严格模式下,全局函数调用时,this
指向undefined
。这使得开发者必须明确this
的指向,避免错误。'use strict'; function foo() { console.log(this); // undefined } foo();
禁止使用八进制数字字面量
在非严格模式下,以
0
开头的数字字面量被认为是八进制数,例如010
表示十进制的 8。严格模式禁止这种写法。'use strict'; var num = 010; // SyntaxError: Octal literals are not allowed in strict mode.
eval()
作用域限制在非严格模式下,
eval()
执行的代码可以修改外部作用域的变量。在严格模式下,eval()
创建的变量会被限制在eval()
内部的作用域中,不会影响外部作用域。
'use strict'; var x = 10; eval('var x = 20;'); console.log(x); // 10 (严格模式下 eval 创建的变量不影响外部作用域)
- 不允许使用
arguments.callee
和arguments.caller
arguments.callee
指向当前正在执行的函数, arguments.caller
指向调用当前函数的函数。 这两者在严格模式下被禁用,因为它们在某些场景下会影响代码性能和安全性。
-- -------------------- ---- ------- ---- -------- -------- ----- - -- ---------- --------- --------- --- ----------- ---------- --- --- -- -------- -- ------ ---- --------- -- --- --------- ------- --- ----- -- ---- ----------------- ----------------- - ------ --- -- --------- ------------------------ ------------- ------------ ------ ---------- ---------- ------------ --------- --------- ------- -- ------------- ---- -------- --- --------- - --- -- ------------ ---------- ------ ---- -------- ---- --- --- ------- - ---------- ---------------------------- - ---------- ------------------------------- - ----------- --------------------------- - ------ ---------- -------- ------------------ ---------- ---------- --- ------- - ----------- -------------------------- - ----------- ---------------------------- --------------------- ---------- ------------