js 严格模式

一、什么是严格模式

严格模式是 ECMAScript 5 引入的一种代码运行模式,它通过限制一些不规范的语法行为、禁止某些潜在的错误操作、抛出更多明确的异常,来让代码运行更安全、更规范,同时也为后续的 ES 版本特性提供了更好的兼容性。

简单来说,严格模式就是给 JavaScript 代码加上了一套「语法约束规则」,让开发者更早发现代码中的问题,减少隐蔽的 bug。

二、如何启用严格模式

严格模式的启用分为「全局启用」和「局部启用」(推荐局部启用),语法非常简单,使用字符串指令 "use strict";(单双引号均可,也可写成 'use strict';)。

1. 全局启用(不推荐,存在隐患)

"use strict"; 放在脚本文件的最顶部(在任何其他代码之前),则整个脚本文件内的代码都将运行在严格模式下。

javascript

运行

javascript 复制代码
// 全局启用严格模式(脚本最顶部,无任何代码前置)
"use strict";

let a = 10;
a = 20; // 正常执行

隐患:如果该脚本文件被其他非严格模式的脚本引入,可能会影响其他脚本的运行;同时,全局严格模式会污染整个作用域,不利于代码模块化。

2. 局部启用(推荐,模块化隔离)

"use strict"; 放在函数体的最顶部,则仅该函数内部的代码运行在严格模式下,外部代码不受影响。这是最安全的方式,尤其适合在函数、对象方法、模块化代码中使用。

javascript

运行

scss 复制代码
// 普通模式(外部代码)
function normalFunc() {
  b = 30; // 普通模式下:未声明的变量会隐式挂载到 window 上,不报错
}

// 局部启用严格模式(函数内部最顶部)
function strictFunc() {
  "use strict";
  let c = 40;
  d = 50; // 严格模式下:会抛出异常,禁止隐式声明全局变量
}

normalFunc(); // 正常执行
strictFunc(); // 报错:ReferenceError: d is not defined

三、严格模式的核心特性(与普通模式的关键区别)

严格模式的核心变化是「禁止不良行为」和「抛出更多异常」,以下是最常用、最关键的几个特性:

1. 禁止隐式声明全局变量(核心变化之一)

普通模式下,未使用 var/let/const 声明的变量,会被隐式挂载到全局对象(浏览器中是 window)上,不会报错,这是很多全局变量污染和 bug 的根源。

严格模式下,未声明直接赋值的变量会抛出 ReferenceError 异常,强制开发者必须显式声明变量。

javascript

运行

javascript 复制代码
"use strict";

// 错误:未声明变量直接赋值,抛出 ReferenceError
x = 100; 

// 正确:显式使用 let/const/var 声明变量
let y = 200;

2. 禁止对只读属性 / 不可写属性 赋值,禁止删除不可配置属性

普通模式下,对只读属性赋值、删除不可配置属性只会「静默失败」(不报错,但操作无效),很难被发现;严格模式下,这些操作会直接抛出 TypeError 异常,明确告知开发者操作无效。

javascript

运行

javascript 复制代码
"use strict";

// 1. 对只读属性赋值(报错)
const obj = Object.defineProperty({}, "name", {
  value: "张三",
  writable: false // 只读属性,不可修改
});
obj.name = "李四"; // 严格模式下:抛出 TypeError: Cannot assign to read only property 'name'

// 2. 删除不可配置属性(报错)
Object.defineProperty(obj, "age", {
  value: 20,
  configurable: false // 不可配置,无法删除
});
delete obj.age; // 严格模式下:抛出 TypeError: Cannot delete property 'age'

3. 禁止删除变量 / 函数 / 函数参数

普通模式下,删除变量(delete a)只会返回 false,静默失败;严格模式下,删除变量、函数、函数参数会抛出 SyntaxErrorReferenceError 异常 ,只有对象的可配置属性才能被 delete

javascript

运行

javascript 复制代码
"use strict";

let num = 10;
function fn() {}

// 错误:删除变量,抛出 SyntaxError
delete num; 

// 错误:删除函数,抛出 SyntaxError
delete fn; 

// 正确:删除对象的可配置属性
let person = { name: "张三" };
delete person.name; // 执行成功,返回 true

4. 禁止函数参数重名

普通模式下,函数参数可以重名(如 function fn(a, a) {}),后面的参数会覆盖前面的;严格模式下,函数参数不能重名 ,否则会抛出 SyntaxError 异常。

javascript

运行

javascript 复制代码
"use strict";

// 错误:参数重名,抛出 SyntaxError
function fn(a, a) { 
  return a + a;
}

// 正确:参数唯一
function fn2(a, b) {
  return a + b;
}

5. this 指向的变化(重要区别)

严格模式下,this 的指向与普通模式有明显不同,主要体现在两个场景:

  • 全局作用域中,普通函数的 this 指向全局对象(浏览器中是 window);严格模式下,全局作用域中普通函数的 thisundefined (不再指向 window)。
  • 构造函数忘记使用 new 调用时,普通模式下 this 指向 window,会隐式创建全局变量;严格模式下,未使用 new 调用构造函数,thisundefined,会抛出 TypeError 异常

javascript

运行

javascript 复制代码
"use strict";

// 场景 1:全局函数的 this 为 undefined
function globalFunc() {
  console.log(this); // 输出:undefined
}
globalFunc();

// 场景 2:构造函数忘记 new 调用(报错)
function Person(name) {
  this.name = name; // 严格模式下:抛出 TypeError: Cannot set property 'name' of undefined
}
let p = Person("张三"); // 未使用 new,直接调用

6. 禁止使用一些保留字不规范语法

严格模式下,禁止使用 ES 保留字作为变量名 / 函数名(如 let, const, class, export, import 等),同时禁止一些不规范的语法(如 with 语句、arguments.calleearguments.caller 等),使用这些语法会抛出异常。

javascript

运行

javascript 复制代码
"use strict";

// 错误:使用 with 语句,抛出 SyntaxError(严格模式禁止 with)
with (Math) {
  console.log(sqrt(16));
}

// 错误:使用 arguments.callee,抛出 TypeError(严格模式禁止)
function factorial(n) {
  return n <= 1 ? 1 : n * arguments.callee(n - 1);
}

四、严格模式与之前 for...inconst 的关联

补充说明你上一个问题中 for...in 循环使用 const 与严格模式的关系:

  1. for...in/for...of 循环中使用 const 声明迭代变量,在严格模式和普通模式下都可以正常运行,不会因为严格模式而报错;
  2. 严格模式不会改变「for...in 每次迭代创建全新变量绑定」的机制,const 声明的迭代变量依然符合「不重新赋值」的约束,因此可以正常使用;
  3. 反而,严格模式会禁止 for...in 循环中一些不规范的操作(如迭代变量未声明),让代码更严谨。

javascript

运行

javascript 复制代码
"use strict";

// 严格模式下,for...in 用 const 声明迭代变量,正常执行
for (const propName in window) {
  console.log(propName);
}

总结

  1. 严格模式通过 "use strict"; 启用,推荐局部(函数内)启用,避免污染全局作用域;
  2. 核心特性是「禁止不良行为、抛出更多异常」,关键包括禁止隐式全局变量、禁止参数重名、this 指向变化等;
  3. 严格模式让代码更安全、更规范,减少隐蔽 bug,是现代 JavaScript 开发的良好实践;
  4. for...in 中使用 const 在严格模式下完全兼容,不受严格模式影响。
相关推荐
聪明的Levi1 天前
FRONT END REVIEW
前端·css·html
仙人掌一号1 天前
React 白屏机制原理分析[共1500字,阅读时长8min]
前端·javascript·面试
sophie旭1 天前
Suspense+React.lazy--组件渲染如何暂停 → 等待 → 恢复
前端·javascript·react.js
我的div丢了肿么办1 天前
js中worker的详细讲解
前端·javascript·vue.js
三十_1 天前
WebRTC 入门:一分钟理解会议系统的三种架构(Mesh/SFU/MCU)
前端·后端·webrtc
陈泡泡_1 天前
Android抓取trace的几种方式
前端
外啫啫1 天前
vue3实现前端生成word并下载
前端·javascript
Cache技术分享1 天前
282. Java Stream API - 从 Collection 或 Iterator 创建 Stream
前端·后端
豆豆1 天前
主流的企业建站方式,sass云建站和自助建站系统怎么选择?
前端·css·低代码·cms·sass·低代码平台·站群