当前位置: 首页 > news >正文

js严格模式和非严格模式

好的,这是一个非常基础且重要的概念。我们来详细解析一下 JavaScript 中的严格模式(Strict Mode)和非严格模式(Sloppy Mode)。

可以把它想象成参加一场考试:

  • 非严格模式:就像是开卷、不计时的随堂测验,规则很宽松,写得不那么标准也能得分,老师会尽量“猜测”你的意图。
  • 严格模式:就像是正式的闭卷大考,有严格的规范,任何不符合规则的写法都会被立刻标记为错误,不留任何情面。

1. 什么是严格模式?

严格模式 (Strict Mode) 是在 ECMAScript 5 (ES5) 中引入的一种选择性加入(opt-in)的机制,它为 JavaScript 代码选择了一种更严格、更受限的语法和错误处理规则。

它的本质是让 JavaScript 引擎以一种更“严谨”的方式来解析和执行你的代码,从而提高代码的健壮性和安全性。

非严格模式 (Sloppy Mode) 则是 JavaScript 默认的、向后兼容的、更“宽容”的模式。

2. 为什么需要严格模式?

JavaScript 最初被设计为一门非常宽容的语言,为了让网页在各种意外情况下都能勉强运行(而不是直接崩溃)。但这种宽容性也导致了一些问题:

  • 静默错误 (Silent Errors):一些本该是错误的操作,在非严格模式下不会报错,只会静默失败,这使得调试变得异常困难。
  • 不安全的行为: 某些语法可能存在安全隐患或导致意外的全局变量污染。
  • 阻碍引擎优化: 一些“坏语法”让 JavaScript 引擎难以对代码进行性能优化。
  • 为未来做准备: 禁止一些未来可能被用作新关键字的保留字。

严格模式的诞生就是为了解决这些历史遗留问题。

3. 如何开启严格模式?

开启严格模式非常简单,只需在代码的特定位置添加一个字符串字面量:

"use strict";

根据你放置的位置,它的作用域也不同:

  • 全局严格模式: 将 "use strict"; 放在脚本文件的最顶部

    // my-script.js
    "use strict";// 整个文件都将以严格模式运行
    let x = 10;
    // ...
    
  • 函数内严格模式: 将 "use strict"; 放在函数体的最顶部

    function myStrictFunction() {"use strict";// 只有这个函数内部是以严格模式运行的let y = 20;// ...
    }
    

一个非常重要的现代知识点:

ES6 模块 (import/export)class 的代码块中,严格模式是默认开启的,你无需手动添加 "use strict";。这就是为什么在现代前端框架(如 React, Vue)的开发中,你很少看到这行代码,因为你写的代码基本上都已经是运行在严格模式下的模块了。


4. 严格模式与非严格模式的主要区别

下面是一些最直观和重要的区别,通过代码对比会非常清晰:

a. 禁止意外创建全局变量

这是最经典的区别。

  • 非严格模式:
    function createGlobal() {mistake = "I am a global variable!"; // 忘记写 let/const/var
    }
    createGlobal();
    console.log(window.mistake); // "I am a global variable!" (在浏览器中)
    // 变量泄漏到了全局作用域,这是一个非常危险的副作用。
    
  • 严格模式:
    "use strict";
    function createGlobal() {mistake = "This will cause an error";
    }
    // createGlobal(); // 这一行会直接抛出 ReferenceError,程序会中断
    
    结论:严格模式将一个常见的“静默错误”变成了“抛出错误”,让你能立刻发现问题。
b. 禁止对只读属性或不可扩展对象进行修改
  • 非严格模式:
    const obj = {};
    Object.defineProperty(obj, 'readOnly', { value: 10, writable: false });obj.readOnly = 20; // 尝试修改只读属性
    console.log(obj.readOnly); // 10 (修改静默失败,不会报错)
    
  • 严格模式:
    "use strict";
    const obj = {};
    Object.defineProperty(obj, 'readOnly', { value: 10, writable: false });// obj.readOnly = 20; // 这一行会抛出 TypeError
    
    结论: 严格模式同样将静默失败的操作变成了明确的错误。
c. this 的指向不同

我们在之前的练习中已经遇到过。

  • 非严格模式:
    function showThis() {console.log(this);
    }
    showThis(); // 在浏览器中,会输出全局的 window 对象
    
  • 严格模式:
    "use strict";
    function showThis() {console.log(this);
    }
    showThis(); // 输出 undefined
    
    结论: 严格模式下的 this 行为更安全,避免了意外地污染全局对象。
d. 禁止重复的参数名
  • 非严格模式:
    function sum(a, a, b) { // 不会报错return a + a + b; // 实际上是第二个 a 生效
    }
    console.log(sum(1, 2, 3)); // 2 + 2 + 3 = 7
    
  • 严格模式:
    "use strict";
    // function sum(a, a, b) { // 这一行在代码解析阶段就会抛出 SyntaxError
    //   return a + b;
    // }
    
    结论: 严格模式在语法层面就杜绝了这种不合理的代码。

总结与建议

特性非严格模式 (Sloppy Mode)严格模式 (Strict Mode)
意外全局变量允许,静默创建禁止,抛出 ReferenceError
修改只读属性静默失败禁止,抛出 TypeError
全局函数this指向全局对象 (window)undefined
重复参数名允许(最后一个生效)禁止,抛出 SyntaxError

最终建议:始终使用严格模式!

在今天,你没有任何理由不使用严格模式。它能帮你写出更健壮、更安全、更规范的代码,并且能让你避免很多难以调试的“幽灵bug”。

鉴于现代 JavaScript 的模块和类已经默认开启了严格模式,将 "use strict"; 放在所有非模块化的老脚本的顶部,应该成为你的一个标准习惯。

http://www.xdnf.cn/news/1076977.html

相关文章:

  • 【Python基础】13 知识拓展:CPU、GPU与NPU的区别和联系
  • 【科研绘图系列】基于R语言的复杂热图绘制教程:环境因素与染色体效应的可视化
  • SeaTunnel 社区月报(5-6 月):全新功能上线、Bug 大扫除、Merge 之星是谁?
  • 基于Spring Cloud微服务架构的API网关方案对比分析
  • 3.1.1.9 安全基线检查项目九:检查是否设置限制su命令用户组
  • [C#] WPF - 自定义样式(Slider篇)
  • 位运算经典题解
  • ELK日志分析系统(filebeat+logstash+elasticsearch+kibana)
  • Python 库 包 nltk (Natural Language Toolkit)
  • 视频断点续播全栈实现:基于HTML5前端与Spring Boot后端
  • 141.在 Vue 3 中使用 OpenLayers Link 交互:把地图中心点 / 缩放级别 / 旋转角度实时写进 URL,并同步解析显示
  • 【Maven 】 <resources> 配置中排除 fonts/** 目录无效,可能是由于以下原因及解决方案:
  • 计算机网络(二)应用层HTTP协议
  • (LangChain)RAG系统链路向量存储之Milvus(四)
  • 【1.4 漫画PostgreSQL高级数据库及国产数据库对比】
  • 【MyBatis保姆级教程下】万字XML进阶实战:配置指南与深度解析
  • 2025年6月28和29日复习和预习(C++)
  • JVM调优实战 Day 15:云原生环境下的JVM配置
  • SQLite与MySQL:嵌入式与客户端-服务器数据库的权衡
  • sqlmap学习ing(2.[第一章 web入门]SQL注入-2(报错,时间,布尔))
  • C++ 第四阶段 STL 容器 - 第九讲:详解 std::map 与 std::unordered_map —— 关联容器的深度解析
  • 解决安装UBUNTU20.04 提示尝试将SCSI(0,0,0),第一分区(sda)设备的一个vfat文件系统挂载到/boot/efi失败...问题
  • poi java设置字体样式
  • 数据结构day4——栈
  • WPF学习笔记(18)触发器Trigger
  • Cypher 是 Neo4j 专用的查询语言
  • 归因问答-有效归因实践
  • 笔记本电脑怎样投屏到客厅的大电视?怎样避免将电脑全部画面都投出去?
  • Nginx重定向协议冲突解决方案:The plain HTTP request was sent to HTTPS port
  • Qt中使用QSettings数据或结构体到INI文件