查看: 64|回覆: 1

Web前端入门第 55 问:JavaScript 严格模式与非严格模式区别

[複製鏈接]

3

主題

0

回帖

0

積分

热心网友

金币
0
閲讀權限
220
精華
0
威望
0
贡献
0
在線時間
0 小時
註冊時間
2008-3-22
發表於 2025-5-20 09:08:00 | 顯示全部樓層 |閲讀模式

JavaScript 默认是非严格模式的,可以通过 "use strict"; 启用严格模式。此声明语句可以放在 JS 文件顶部,也可以放在函数内部。

启用严格模式

1、外部脚本在 JS 文件开头声明,内部脚本在 <script> 标签开头声明,声明后所有 JS 代码启用严格模式:

"use strict";

console.log('Hello World!');

错误写法:

console.log("test");
"use strict"; // 置于代码之后的声明,严格模式不生效!

2、在函数内部声明函数启用严格模式,此时本函数体内部的 JS 代码将启用严格模式:

function strictFunc() {
  "use strict"; // 函数级严格模式
  let x = 10;
  y = 20; // ReferenceError: y is not defined
}

function nonStrictFunc() {
  y = 20; // 非严格模式下隐式创建全局变量(不推荐)
}

错误写法:

if (true) {
  "use strict"; // 无效!严格模式无法在块级作用域启用
  x = 10; // 非严格模式下隐式创建全局变量
}

3、模块化脚本(ES6 Modules)无需显式声明,默认启用严格模式:

// module.js(无需写 "use strict")
export default function() {
  x = 10; // ReferenceError: x is not defined
}

4、类(ES6 Class)声明或类方法内部无需显式声明默认启用严格模式:

class MyClass {
  constructor() {
    x = 10; // ReferenceError: x is not defined
  }
}

为何 JS 代码会有两种不同的解析结果?

这就不得不提到历史原因了,JS 之父创造 JavaScript 时,仅用了 10 天时间,这久导致了 JS 在后来使用中发现了一些问题,又由于浏览器的版本迭代必须要兼顾一些旧的代码(不可能浏览器来一个版本更新,直接把所有网站一棒打死),所以就有了 严格模式 的出现,这个模式的用途就是告诉浏览器,我这个网站的代码你按照 严格模式 来解析,无需考虑历史兼容性,可能存在的隐式错误可以先告诉我。

严格模式 vs 非严格模式

主要区别如下:

变量声明

非严格模式:未声明的变量赋值会隐式创建全局变量。

严格模式:未声明的变量赋值会抛出 ReferenceError。

<script>
  function test1 () {
    y = 10; // 声明为全局变量
  }
  test1();
  console.log(y); // 10
</script>
<script>
  function test2 () {
    "use strict";
    x = 10; // ReferenceError: x is not defined
  }
  test2();
  console.log(x); // test2 报错,此行代码不执行
</script>

静默错误转显式错误

删除不可删除的属性:delete Object.prototype; 在严格模式下报错。

重复参数名:function(a, a) {} 在严格模式下报语法错误。

只读属性赋值:NaN = 1; 在严格模式下报错。

<script>
  function test1 (a, a) {
    delete Object.prototype;
    NaN = 1;
  }
  test1();
</script>
<script>
  "use strict";
  function test2 (a, a1) { // 报错 SyntaxError
    delete Object.prototype; // 报错 TypeError
    NaN = 1; // 报错 TypeError
  }
  test2();
</script>

this 指向

非严格模式:全局函数中 this 指向全局对象(如 window)。

严格模式:全局函数中 this 为 undefined。

<script>
  function test1 () {
    console.log(this); // 浏览器中指向 Window 对象,nodejs 中指向 global 对象
  }
  test1();
</script>
<script>
  "use strict";
  function test2 () {
    console.log(this); // undefined
  }
  test2();
</script>

eval 和 arguments 限制

eval 变量泄漏:严格模式下 eval 中的变量不会污染外部作用域。

禁用 arguments.callee:防止递归调用导致性能问题。

<script>
  function test1 () {
    eval('var a = 10');
    console.log(arguments.callee); // 指向函数本身
    console.log(a); // 10
  }
  test1();
</script>
<script>
  "use strict";
  function test2 () {
    eval('var a = 10');
    console.log(arguments.callee); // 报错 TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them
    console.log(a); // ReferenceError: a is not defined
  }
  test2();
</script>

其他限制

八进制表示:禁止 0123,需用 0o123。

with 语句:严格模式下禁用,避免作用域混乱。

保留字限制:如 interface、private 等不能作为变量名。

<script>
  function test1 () {
    console.log(0123); // 83
    with (Math) {
      console.log(random()); // 输出随机数
    }
    var interface = 'str';
    console.log(interface); // str
  }
  test1();
</script>
<script>
  "use strict";
  function test2 () {
    console.log(0123); // SyntaxError: Octal literals are not allowed in strict mode.
    with (Math) { // SyntaxError: Strict mode code may not include a with statement
      console.log(random());
    }
    var interface = 'str'; // SyntaxError: Unexpected strict mode reserved word
    console.log(interface);
  }
  test2();
</script>

写在最后

建议始终启用严格模式,强制更安全的编码实践,避免隐式错误,提升代码质量。

回覆

使用道具 舉報

0

主題

2091

回帖

1萬

積分

琼殿精英

金币
10576
閲讀權限
220
精華
0
威望
0
贡献
0
在線時間
0 小時
註冊時間
2011-10-11
發表於 6 天前 | 顯示全部樓層
感谢楼主的详细分享!这篇关于JavaScript严格模式的总结非常全面,对于前端初学者来说很有帮助。

看完帖子我学到了不少,之前有些细节确实没注意到,比如:

1. 严格模式无法在块级作用域启用,这点以前真没注意过
2. ES6模块和类默认启用严格模式,这个特性很实用
3. with语句在严格模式下被禁用,确实应该避免使用

在实际开发中,我现在基本都会在代码开头加上"use strict",既能避免一些低级错误,也方便团队成员阅读代码时知道这是严格模式。

不过有个小建议,楼主要不要考虑出一期关于严格模式在实际项目中的使用场景?比如在Vue、React这些框架中是否需要手动开启严格模式?因为现在很多项目都用的是ES6模块,感觉这个话题也值得讨论一下。

期待楼主的下一期内容,55问坚持下来很不容易,继续加油![em_2]
回覆

使用道具 舉報

您需要登錄後才可以回帖 登錄 | 立即注册

本版積分規則

圆梦公社,专注于为全球华人提供纯粹技术交流的地方,请勿发布任何政治及违法的言论。如有相关侵权、举报、投诉及建议等,请发 E-mail:dzh188@hotmail.com

Powered by Discuz! X5.0 © 2001-2026 Discuz! Team.

在本版发帖返回顶部