JS 严格模式和正常模式详解

JavaScript 严格模式(Strict Mode)和正常模式(Non-Strict Mode)是用于控制 JavaScript 代码执行的两种不同模式。严格模式引入了一些限制和变化,旨在帮助开发人员编写更可靠、安全和高效的代码。在本文中,我们将详细探讨这两种模式的特点、区别和实例,以帮助您更好地理解它们。

正常模式(Non-Strict Mode)

正常模式是 JavaScript 的默认模式,它在早期版本的 JavaScript 中一直存在。在正常模式下,JavaScript 引擎执行代码时,不会进行额外的限制或错误检查。这意味着在正常模式下,开发人员可以编写更灵活的代码,但也容易引入一些潜在的错误和不安全的行为。

下面是正常模式的一些特点:

1.隐式全局变量:在正常模式下,未使用 var、let 或 const 声明的变量会被视为全局变量。这可能导致变量冲突和不可预测的行为。

2.this 绑定松散:在正常模式下,全局对象的 this 值被视为全局对象自身。这可能导致意外的行为,特别是在函数内部。

3.静默失败:在正常模式下,某些操作会导致静默失败,而不抛出错误。这可能导致开发人员难以诊断和调试问题。

4.变量赋值的宽松规则:正常模式允许在不进行声明的情况下直接赋值给未声明的变量,这可能导致错误的变量名或拼写错误。

5.不严格的语法解析:正常模式下,一些不规范的语法可能被接受,而在严格模式下将被拒绝。

严格模式(Strict Mode)

严格模式是 ECMAScript 5(ES5)中引入的一种更严格的模式,旨在减少常见的编程错误和提高代码质量。在严格模式下,JavaScript 引擎执行代码时会施加额外的限制和错误检查,从而提供更强大的代码分析和更多的运行时错误。

下面是严格模式的一些特点:

1.变量必须声明:在严格模式下,所有变量都必须使用 var、let 或 const 关键字进行声明,否则将抛出错误。这有助于避免意外的全局变量。

2.this 绑定更严格:在严格模式下,函数内部的 this 值不会默认绑定到全局对象,而是为 undefined。这鼓励开发人员明确设置 this 值,减少不确定性。

3.禁止删除变量:在严格模式下,使用 delete 操作符删除变量、函数和函数参数将导致错误。这有助于避免不必要的数据丢失和错误。

4.禁止重复的参数:在严格模式下,函数不允许有重复的参数名,而在正常模式下,重复的参数名不会引发错误。

5.禁止八进制字面量:在严格模式下,八进制字面量(如 0123)将导致错误。在正常模式下,它们将被解释为八进制数。

6.禁止 this 关键字的赋值:在严格模式下,不允许对 this 关键字进行赋值。在正常模式下,这是有效的。

7.保留字作为变量名:在严格模式下,一些保留字(如 arguments 和 eval)不能用作变量名。在正常模式下,这是允许的。

8.禁止对只读属性的赋值:在严格模式下,对只读属性的赋值将导致错误。在正常模式下,这种操作通常不会引发错误。

9.禁止删除不可删除的属性:在严格模式下,使用 delete 操作符删除不可删除的属性将导致错误。在正常模式下,这通常会返回 false,但不会引发错误。

10.更强制的 eval() 行为:在严格模式下,eval() 中的代码无法在其包含的上下文之外创建变量。在正常模式下,它可以创建全局变量。

严格模式 vs. 正常模式:区别和实例

以下是一些示例,说明严格模式和正常模式之间的区别:

变量声明和赋值:

正常模式:

javascript 复制代码
x = 10; // 全局变量 x 被隐式创建

严格模式:

javascript 复制代码
"use strict";
x = 10; // 抛出 ReferenceError:x 未定义

在严格模式下,未声明的变量不能被赋值。

this 绑定:

正常模式:

javascript 复制代码
function doSomething() {
  console.log(this); // 全局对象
}

doSomething();

严格模式:

javascript 复制代码
"use strict";
function doSomething() {
  console.log(this); // undefined
}

doSomething();

在严格模式下,函数内部的 this 不会默认绑定到全局对象。

删除变量:

正常模式:

javascript 复制代码
var x = 10;
delete x; // 返回 true,但 x 未定义

严格模式:

javascript 复制代码
"use strict";
var x = 10;
delete x; // 抛出错误:无法删除

在严格模式下,使用 delete 删除变量将导致错误。

重复的参数名:

正常模式:

javascript 复制代码
function sum(x, x) {
  return x + x;
}

console.log(sum(1, 2)); // 4

严格模式:

javascript 复制代码
"use strict";
function sum(x, x) {
  return x + x;
}

console.log(sum(1, 2)); // 抛出 SyntaxError:参数名重复

在严格模式下,函数不允许有重复的参数名。

八进制字面量:

正常模式:

javascript 复制代码
var num = 0123; // 八进制字面量
console.log(num); // 83

严格模式:

javascript 复制代码
"use strict";
var num = 0123; // 抛出 SyntaxError:八进制字面量无效

在严格模式下,八进制字面量将导致错误。

this 关键字的赋值:

正常模式:

javascript 复制代码
function changeThis() {
  this = 42; // 有效
}

changeThis();

严格模式:

javascript 复制代码
"use strict";
function changeThis() {
  this = 42; // 抛出 TypeError:无法分配给"this"
}

changeThis();

在严格模式下,不允许对 this 关键字进行赋值。

只读属性的赋值:

正常模式:

javascript 复制代码
var obj = {};
Object.defineProperty(obj, "x", { value: 42, writable: false });

obj.x = 10; // 不会报错,但 x 的值不会改变

严格模式:

javascript 复制代码
"use strict";
var obj = {};
Object.defineProperty(obj, "x", { value: 42, writable: false });

obj.x = 10; // 抛出 TypeError:只读属性无法修改

在严格模式下,对只读属性的赋值将导致错误。

删除不可删除的属性:

正常模式:

javascript 复制代码
var obj = {};
Object.defineProperty(obj, "x", { value: 42, configurable: false });

delete obj.x; // 返回 false,但属性未删除

严格模式:

javascript 复制代码
"use strict";
var obj = {};
Object.defineProperty(obj, "x", { value: 42, configurable: false });

delete obj.x; // 抛出 TypeError:无法删除属性

在严格模式下,使用 delete 删除不可删除的属性将导致错误。

保留字作为变量名:

正常模式:

javascript 复制代码
var arguments = 42; // 有效
console.log(arguments); // 42

严格模式:

javascript 复制代码
"use strict";
var arguments = 42; // 抛出 SyntaxError:无法将保留字用作变量名

在严格模式下,一些保留字不能用作变量名。

eval() 行为:

正常模式:

javascript 复制代码
var x = 1;
eval("var x = 2;");
console.log(x); // 2,全局 x 被修改

严格模式:

javascript 复制代码
"use strict";
var x = 1;
eval("var x = 2;");
console.log(x); // 1,全局 x 未被修改

在严格模式下,eval() 中的代码无法在其包含的上下文之外创建变量。

使用严格模式的好处

使用严格模式有助于改善代码质量、降低错误风险并提高性能。以下是一些使用严格模式的好处:

1.更安全的代码:严格模式可以帮助您捕获一些潜在的错误,例如意外的全局变量、不安全的 this 绑定和禁止 eval() 中的变量泄漏。

2.更高效的 JavaScript:严格模式下,引擎可以进行更多的优化,从而提高代码的执行速度。

3.更易维护的代码:严格模式要求更规范的代码编写,更少的潜在陷阱和更明确的行为,从而使代码更容易理解和维护。

4.避免未来的冲突:ECMAScript 规范将来可能会引入新的保留字和语法。使用严格模式可以避免与未来版本的冲突。

5.更好的错误报告:严格模式下,运行时错误更容易捕获,因为它会抛出更多的异常,而不是静默失败。

6.减少全局污染:严格模式可以减少全局变量的污染,因为它要求显式声明变量。

启用严格模式

要在 JavaScript 中启用严格模式,您只需在脚本或函数的顶部添加特定的字符串:

javascript 复制代码
"use strict";

如果您将这个字符串添加到脚本的顶部,整个脚本都将在严格模式下执行。如果您只希望在特定函数内启用严格模式,可以将字符串添加到该函数的顶部。

例如:

javascript 复制代码
"use strict";

function myFunction() {
  // 这里是严格模式
}

function anotherFunction() {
  // 这里不是严格模式
}

严格模式的适用性和最佳实践

尽管严格模式提供了许多好处,但并不是所有情况下都需要使用它。以下是一些使用严格模式的适用性和最佳实践:

  1. 新项目和新代码:对于新项目和新代码,建议启用严格模式,以避免常见的错误和提高代码质量。
    2.旧项目:在旧项目中,启用严格模式可能会导致一些现有代码不起作用。因此,在将严格模式引入现有项目之前,需要进行充分的测试和修复。
    3.特定函数:如果只需要在特定函数内使用严格模式,可以在该函数的顶部启用严格模式,而不必影响整个脚本。
    4.尊重第三方库:在使用第三方库或框架时,应尊重库的规则,不强制启用严格模式。如果库允许,您可以在自己的代码中启用严格模式。
    5.测试和部署:在使用严格模式的代码中,务必进行充分的测试,以确保它正常工作。在部署之前,确保您的代码在严格模式和正常模式下都能正确运行。

总之,JavaScript 严格模式是一个有助于提高代码质量和性能的有用工具。通过了解其特点和使用最佳实践,您可以更好地应用它来编写更可靠和安全的 JavaScript 代码。然而,根据项目的需求和现有的代码基础,您应该权衡是否使用严格模式,以确保最佳的开发和维护体验。

相关推荐
web行路人27 分钟前
React中类组件和函数组件的理解和区别
前端·javascript·react.js·前端框架
番茄小酱00128 分钟前
Expo|ReactNative 中实现扫描二维码功能
javascript·react native·react.js
子非鱼9211 小时前
【Ajax】跨域
javascript·ajax·cors·jsonp
超雄代码狂1 小时前
ajax关于axios库的运用小案例
前端·javascript·ajax
周亚鑫2 小时前
vue3 pdf base64转成文件流打开
前端·javascript·pdf
落魄小二2 小时前
el-table 表格索引不展示问题
javascript·vue.js·elementui
y5236482 小时前
Javascript监控元素样式变化
开发语言·javascript·ecmascript
fruge2 小时前
纯css制作声波扩散动画、js+css3波纹催眠动画特效、【css3动画】圆波扩散效果、雷达光波效果完整代码
javascript·css·css3
neter.asia2 小时前
vue中如何关闭eslint检测?
前端·javascript·vue.js
嚣张农民2 小时前
JavaScript中Promise分别有哪些函数?
前端·javascript·面试