推荐答案
严格模式 ('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 指向调用当前函数的函数。 这两者在严格模式下被禁用,因为它们在某些场景下会影响代码性能和安全性。
// www.javascriptcn.com code example
'use strict';
function foo() {
// TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them
arguments.callee;
arguments.caller;
}
foo();
```
9. **保留关键字**
在严格模式下,一些保留关键字不能用作变量名,例如 `implements`, `interface`, `let`, `package`, `private`, `protected`, `public`, `static`, `yield` 等。
```javascript
'use strict';
var protected = 10; // SyntaxError: Unexpected strict mode reserved word
```
### 严格模式的优点
* **更易于调试:** 严格模式下的一些错误会被直接抛出,更容易定位和修复错误。
* **代码更规范:** 严格模式有助于养成良好的编程习惯,提高代码的可读性和可维护性。
* **更高的安全性:** 严格模式禁止了一些不安全的行为,可以提高代码的安全性。
* **为未来的 JavaScript 版本做准备:** 严格模式下的限制和规则,可能在未来的 JavaScript 版本中变成强制性的。
### 严格模式的缺点
* **不兼容旧代码:** 严格模式可能会使一些旧的、不规范的代码无法正常运行。
* **需要额外注意:** 使用严格模式需要开发者更加注意代码的细节,避免出现错误。
尽管有一些缺点,但严格模式仍然被认为是现代 JavaScript 开发中必不可少的一部分。