什么是 javascript 中的严格模式

在这里插入图片描述

在现代 Web 前端开发实践中,JavaScript 语言的演进始终围绕着提升代码的可维护性、安全性和执行效率展开。ECMAScript 5 引入的“严格模式”(Strict Mode)是这一演进过程中的里程碑特性,它通过启用一组更严格的解析和错误处理机制,帮助开发者规避语言中危险或模糊的语法特性,从而构建更健壮、可预测的应用程序。作为资深前端开发专家,深入理解并正确应用严格模式,是编写高质量、可协作、可调试代码的必备技能。

严格模式的基本概念与核心作用

严格模式是一种编译指示(pragma),通过在脚本或函数的顶部添加 "use strict"; 字面量指令来激活。该指令并非语句,而是一个被早期 JavaScript 引擎忽略的字符串表达式,现代引擎则将其识别为开启严格模式的信号。

严格模式的核心作用在于:

  1. 捕获常见编码错误:将原本静默失败的错误(silent errors)转化为显式的运行时错误(throwing errors),便于开发者及时发现和修复。
  2. 防止意外的全局变量创建:在非严格模式下,对未声明的变量赋值会自动创建全局变量,这是许多 bug 的根源。严格模式禁止此行为。
  3. 消除 this 的自动装箱:在非严格模式下,函数内部的 this 在非对象调用时会自动绑定到全局对象(如 window)。严格模式下,this 保持为 undefined,避免了意外的全局状态污染。
  4. 禁止使用模糊或保留的语法:例如,禁止函数参数重名、禁止八进制字面量、禁止 with 语句和 eval 的某些危险用法。
  5. 提升优化潜力:由于严格模式限制了某些可能导致歧义的行为,JavaScript 引擎可以进行更激进的优化,理论上提升执行性能。

严格模式可以作用于全局作用域(整个脚本)或局部作用域(单个函数),其影响范围遵循词法作用域规则。

示例一:意外全局变量的防止

非严格模式下,拼写错误或遗漏 var/let/const 会导致意外创建全局变量,污染全局命名空间。

// 非严格模式(默认)
function badFunction() {
  typoVariable = "I'm global!"; // 意外创建全局变量,无错误
}
badFunction();
console.log(window.typoVariable); // 输出: "I'm global!" (在浏览器中)

// 严格模式
function goodFunction() {
  "use strict";
  // typoVariable = "This will throw"; // Uncaught ReferenceError: typoVariable is not defined
  // 正确做法
  let typoVariable = "This is local";
  console.log(typoVariable);
}
goodFunction();
// console.log(window.typoVariable); // undefined

goodFunction 中,尝试给未声明的 typoVariable 赋值会立即抛出 ReferenceError,强制开发者显式声明变量,极大地提升了代码的健壮性。

示例二:this 绑定行为的改变

this 的绑定机制是 JavaScript 中最易混淆的部分之一。严格模式简化了其行为。

// 非严格模式
const obj = {
  name: "Object",
  getName: function() {
    console.log(this.name);
  }
};

// 正常调用
obj.getName(); // 输出: Object

// 独立函数调用,this 绑定到全局对象
const standalone = obj.getName;
standalone(); // 输出: undefined (如果 window.name 未定义) 或全局 name 值

// 严格模式
const strictObj = {
  name: "StrictObject",
  getNameStrict: function() {
    "use strict"; // 也可以在函数内启用
    console.log(this?.name || 'this is undefined');
  }
};

strictObj.getNameStrict(); // 输出: StrictObject

const strictStandalone = strictObj.getNameStrict;
strictStandalone(); // 输出: this is undefined (this is undefined in strict mode)

strictStandalone() 调用中,非严格模式下 this 指向 window,可能导致意外行为。严格模式下 thisundefined,输出清晰表明上下文丢失,有助于快速定位问题。

示例三:禁止函数参数重名与 arguments 的规范化

严格模式禁止函数参数重名,这有助于避免因参数覆盖导致的逻辑错误。

// 非严格模式
function duplicateParams(a, a, b) { // 允许,但第二个 a 覆盖第一个
  console.log(a, b); // 输出第二个 a 和 b 的值
  console.log(arguments[0]); // 第一个传入的 a
  console.log(arguments[1]); // 第二个传入的 a (也是参数 a 的当前值)
  // arguments 对象与参数变量是动态关联的
  a = 100;
  console.log(arguments[0]); // 100 (变化同步)
}
duplicateParams(1, 2, 3); // 输出: 2 3, 然后 arguments[0] 也变为 100

// 严格模式
function strictParams(a, a, b) { // SyntaxError: Duplicate parameter name not allowed in this context
  "use strict";
  // 即使函数体为空,声明时就会报错
}
// 严格模式下必须使用唯一参数名
function uniqueParams(x, y, z) {
  "use strict";
  // arguments 对象不再与参数变量绑定
  x = 100;
  console.log(arguments[0]); // 仍为传入的原始值,不会随 x 变化
  console.log(arguments.length); // 正确反映调用时的参数数量
}
uniqueParams(1, 2);
console.log(uniqueParams.length); // 3 (函数的形参长度)

此外,严格模式下 arguments 对象的行为更符合预期,其属性与命名参数不再保持双向绑定,避免了复杂的副作用。

示例四:禁止 with 语句与限制 eval

with 语句会动态改变作用域链,导致代码难以静态分析和优化,是严格模式明确禁止的。

const obj = { prop: "value" };

// 非严格模式
function withExample() {
  with (obj) {
    console.log(prop); // "value" - prop 在 obj 的作用域内查找
    newProp = "new"; // 在非严格模式下,可能创建全局变量 newProp
  }
  console.log(window.newProp); // "new" (如果在浏览器中)
}
withExample();

// 严格模式
function strictWithExample() {
  "use strict";
  // with (obj) { // SyntaxError: Strict mode code may not include a with statement
  //   console.log(prop);
  // }
}

eval 在严格模式下也有重要变化:它创建的变量和函数仅存在于 eval 调用的上下文中,不会污染外部作用域。

// 非严格模式
eval("var evalVar = 'global'; function evalFunc() {}");
console.log(typeof evalVar); // "string"
console.log(typeof evalFunc); // "function"

// 严格模式
function strictEval() {
  "use strict";
  eval("var evalVarStrict = 'local'; function evalFuncStrict() {}");
  // console.log(evalVarStrict); // ReferenceError: evalVarStrict is not defined
  // console.log(evalFuncStrict); // ReferenceError: evalFuncStrict is not defined
  // 变量和函数仅在 eval 字符串内部有效
}
strictEval();

示例五:模块化与现代框架中的默认严格模式

在 ES6 模块(ESM)和现代前端框架(如 React, Vue, Angular)的构建流程中,严格模式通常是默认启用的。

// ES6 Module (myModule.js)
// 整个模块文件自动运行在严格模式下,无需显式声明
export function moduleFunction() {
  // 此处自动为严格模式
  // duplicateParam = "no var"; // ReferenceError
  return this; // 在模块顶层函数中,this 为 undefined
}

// React 组件 (使用 Babel/Webpack)
function MyComponent() {
  // JSX 编译后的代码通常在严格模式下执行
  const handleClick = () => {
    // 箭头函数的 this 继承自外层,但外层函数在严格模式下 this 为 undefined
    console.log(this); // undefined
  };
  return <button onClick={handleClick}>Click</button>;
}

// Node.js CommonJS 模块
// Node.js 中的 .mjs 文件或通过 --use-strict 标志启用
// 或在 .js 文件顶部添加 "use strict" 以确保严格模式
"use strict";
function nodeFunction() {
  // 安全的 Node.js 代码
}

了解这一点至关重要,因为它意味着在这些环境中,非严格模式下的“侥幸”代码(如省略变量声明)会立即失败。

实际开发中的高级技巧与最佳实践

在大型前端项目中,应始终将严格模式作为标准实践。建议在每个脚本文件的顶部或每个函数的顶部(对于遗留代码)显式添加 "use strict";。对于新项目,优先使用 ES6 模块,其自动启用严格模式。在使用 Webpack、Vite 等构建工具时,确保 Babel 配置(如 @babel/preset-env)正确转换代码,保持严格模式语义。在代码审查中,将非严格模式的代码视为潜在风险点。此外,严格模式与 const/let 的块级作用域、class 语法、模块化等现代特性协同工作,共同构建了一个更安全、更可预测的 JavaScript 开发环境。理解严格模式不仅是掌握语法,更是培养严谨编程思维的关键一步。


欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。


推荐:DTcode7的博客首页。
一个做过前端开发的产品经理,经历过睿智产品的折磨导致脱发之后,励志要翻身农奴把歌唱,一边打入敌人内部一边持续提升自己,为我们广大开发同胞谋福祉,坚决抵制睿智产品折磨我们码农兄弟!


专栏系列(点击解锁)学习路线(点击解锁)知识定位
《微信小程序相关博客》持续更新中~结合微信官方原生框架、uniapp等小程序框架,记录请求、封装、tabbar、UI组件的学习记录和使用技巧等
《AIGC相关博客》持续更新中~AIGC、AI生产力工具的介绍,例如stable diffusion这种的AI绘画工具安装、使用、技巧等总结
《HTML网站开发相关》《前端基础入门三大核心之html相关博客》前端基础入门三大核心之html板块的内容,入坑前端或者辅助学习的必看知识
《前端基础入门三大核心之JS相关博客》前端JS是JavaScript语言在网页开发中的应用,负责实现交互效果和动态内容。它与HTML和CSS并称前端三剑客,共同构建用户界面。
通过操作DOM元素、响应事件、发起网络请求等,JS使页面能够响应用户行为,实现数据动态展示和页面流畅跳转,是现代Web开发的核心
《前端基础入门三大核心之CSS相关博客》介绍前端开发中遇到的CSS疑问和各种奇妙的CSS语法,同时收集精美的CSS效果代码,用来丰富你的web网页
《canvas绘图相关博客》Canvas是HTML5中用于绘制图形的元素,通过JavaScript及其提供的绘图API,开发者可以在网页上绘制出各种复杂的图形、动画和图像效果。Canvas提供了高度的灵活性和控制力,使得前端绘图技术更加丰富和多样化
《Vue实战相关博客》持续更新中~详细总结了常用UI库elementUI的使用技巧以及Vue的学习之旅
《python相关博客》持续更新中~Python,简洁易学的编程语言,强大到足以应对各种应用场景,是编程新手的理想选择,也是专业人士的得力工具
《sql数据库相关博客》持续更新中~SQL数据库:高效管理数据的利器,学会SQL,轻松驾驭结构化数据,解锁数据分析与挖掘的无限可能
《算法系列相关博客》持续更新中~算法与数据结构学习总结,通过JS来编写处理复杂有趣的算法问题,提升你的技术思维
《IT信息技术相关博客》持续更新中~作为信息化人员所需要掌握的底层技术,涉及软件开发、网络建设、系统维护等领域的知识
《信息化人员基础技能知识相关博客》无论你是开发、产品、实施、经理,只要是从事信息化相关行业的人员,都应该掌握这些信息化的基础知识,可以不精通但是一定要了解,避免日常工作中贻笑大方
《信息化技能面试宝典相关博客》涉及信息化相关工作基础知识和面试技巧,提升自我能力与面试通过率,扩展知识面
《前端开发习惯与小技巧相关博客》持续更新中~罗列常用的开发工具使用技巧,如 Vscode快捷键操作、Git、CMD、游览器控制台等
《photoshop相关博客》持续更新中~基础的PS学习记录,含括PPI与DPI、物理像素dp、逻辑像素dip、矢量图和位图以及帧动画等的学习总结
日常开发&办公&生产【实用工具】分享相关博客》持续更新中~分享介绍各种开发中、工作中、个人生产以及学习上的工具,丰富阅历,给大家提供处理事情的更多角度,学习了解更多的便利工具,如Fiddler抓包、办公快捷键、虚拟机VMware等工具

吾辈才疏学浅,摹写之作,恐有瑕疵。望诸君海涵赐教。望轻喷,嘤嘤嘤
非常期待和您一起在这个小小的网络世界里共同探索、学习和成长。愿斯文对汝有所裨益,纵其简陋未及渊博,亦足以略尽绵薄之力。倘若尚存阙漏,敬请不吝斧正,俾便精进!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

DTcode7

客官,赏个铜板吧

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值