JavaScript 中的变量提升与脚本作用域详解

风辰同学_6213

风辰同学_6213

2025-12-29

1010人浏览

原创

JavaScript 中的变量提升与脚本作用域详解

本文深入解析 `var` 提升(hoisting)机制为何在同页面不同 `<script>` &#26631;&#31614;&#20013;&#22833;&#25928;&#65292;&#38416;&#26126;<a style="color:#f60; text-decoration:underline;" title= "&#20316;&#29992;&#22495;"href="https://m.php.cn/zt/35787.html" target="_blank">&#20316;&#29992;&#22495;&#36793;&#30028;&#22914;&#20309;&#23548;&#33268; `referenceerror` &#32780;&#38750; `undefined`&#65292;&#24182;&#23545;&#27604; `let`/`const` &#30340;&#26102;&#24207;&#27515;&#21306;&#29305;&#24615;&#65292;&#24110;&#21161;&#24320;&#21457;&#32773;&#35268;&#36991;&#24120;&#35265;&#38519;&#38449;&#12290;</script>

在 JavaScript 中,var 声明确实会被“提升”(hoisting)——即变量声明会被移动到其所在作用域的顶部,但仅限于当前作用域内。关键点在于:每个 <script> &#26631;&#31614;&#37117;&#26500;&#25104;&#19968;&#20010;&#29420;&#31435;&#30340;&#20840;&#23616;&#25191;&#34892;&#19978;&#19979;&#25991;&#65288;&#21363;&#29420;&#31435;&#30340;&#20316;&#29992;&#22495;&#65289;</script>,它们之间不共享变量声明,即使位于同一 HTML 页面中。

为什么跨 <script> &#26631;&#31614;&#35775;&#38382;&#20250;&#25253;&#38169;&#65311;</script>

看这个例子:

  <script>
    console.log(x); // ❌ Uncaught ReferenceError: x is not defined
  </script><script>
    var x = 10;
  </script>

虽然 var x 在第二段脚本中声明,但第一段脚本完全不知道它的存在——因为 var x 的提升只发生在它所在的 <script> &#20869;&#37096;&#20316;&#29992;&#22495;&#20013;&#12290;&#31532;&#19968;&#27573;&#33050;&#26412;&#20013;&#26082;&#26080;&#22768;&#26126;&#20063;&#26080;&#23450;&#20041;&#65292;x &#26159;&#24443;&#24213;&#26410;&#22768;&#26126;&#65288;undeclared&#65289;&#65292;&#22240;&#27492;&#35302;&#21457; ReferenceError&#65292;&#32780;&#38750; undefined&#12290;</script>

✅ undefined 出现在“已声明但未初始化”的情况; ❌ ReferenceError 出现在“根本未声明”的情况。

为什么同个 <script> &#20869;&#21364;&#36755;&#20986; undefined&#65311;</script>

  <script>
    console.log(x); // ✅ 输出 undefined
    var x = 10;
  </script>

这是因为 var x 的声明被提升到了该 <script> &#20316;&#29992;&#22495;&#39030;&#37096;&#65288;&#31561;&#20215;&#20110; var x; &#34987;&#33258;&#21160;&#21069;&#32622;&#65289;&#65292;&#20294;&#36171;&#20540; x = 10 &#20173;&#20445;&#30041;&#22312;&#21407;&#20301;&#32622;&#12290;&#25191;&#34892;&#26102;&#27969;&#31243;&#22914;&#19979;&#65306;</script>

var x;          // 提升:声明存在,值为 undefined
console.log(x); // → undefined
x = 10;         // 初始化:此时才赋值

这就是典型的 var 提升行为:声明提升 + 初始化不提升。

let 和 const 的行为更严格(推荐使用)

现代 JavaScript 推荐用 let 和 const 替代 var,它们也存在“提升”,但处于暂时性死区(Temporal Dead Zone, TDZ):在声明语句执行前访问变量,会直接抛出 ReferenceError,而非返回 undefined。

JavaScript 测试模式
JavaScript 测试模式

使用 Jest、Vitest 和 Testing Library 实施全面的测试策略,包括单元测试、集成测试和端到端测试,涵盖模拟、测试夹具和测试驱动开发。在编

下载
  <script>
    console.log(y); // ❌ ReferenceError: Cannot access 'y' before initialization
    let y = 20;
  </script>

TDZ 的设计初衷正是为了暴露潜在错误,避免 var 那种静默返回 undefined 导致的隐蔽逻辑 bug。

补充说明:能否让后定义的变量被前置脚本访问?

常规 <script> &#25353;&#39034;&#24207;&#21516;&#27493;&#25191;&#34892;&#65292;&#26080;&#27861;&#36328;&#26631;&#31614;&#20849;&#20139;&#22768;&#26126;&#12290;&#20294;&#33509;&#20351;&#29992;&#27169;&#22359;&#21270;&#26041;&#24335;&#65292;&#21487;&#20511;&#21161; type="module" &#23454;&#29616;<strong>&#24310;&#36831;&#25191;&#34892; + &#39030;&#23618;&#20316;&#29992;&#22495;&#20849;&#20139;&#65288;&#38656;&#27880;&#24847;&#27169;&#22359;&#40664;&#35748;&#26159;&#20005;&#26684;&#27169;&#24335;&#19988;&#26377;&#20316;&#29992;&#22495;&#38548;&#31163;&#65289;&#65306;</script>

  <script type="module">
    console.log(x); // ✅ 正常输出 10(前提是 x 已在同模块或导入中声明)
  </script><script>
    var x = 10; // ⚠️ 注意:此 x 不在模块作用域内!模块无法访问此全局 var
  </script>

⚠️ 实际上,上述模块脚本依然无法访问第二个 <script> &#20013;&#30340; var x</script>,因为模块拥有自己的顶级作用域,不继承传统 <script> &#30340;&#20840;&#23616;&#23646;&#24615;&#65288;&#38500;&#38750;&#26174;&#24335;&#25346;&#36733;&#21040; window&#65289;&#12290;&#30495;&#27491;&#21487;&#34892;&#30340;&#26041;&#24335;&#26159;&#32479;&#19968;&#20351;&#29992;&#27169;&#22359;&#35821;&#27861;&#24182;&#23548;&#20986;/&#23548;&#20837;&#65306;</script>

<script type="module">
  import { x } from './vars.js';
  console.log(x); // ✅
</script><script type="module" src="./vars.js"></script>

总结与最佳实践

  • ✅ var 提升仅限单个 <script>&#65288;&#25110;&#20989;&#25968;&#65289;&#20316;&#29992;&#22495;&#20869;&#65307;&#36328; <script> &#26631;&#31614;&#19981;&#20849;&#20139;&#22768;&#26126;&#65307;</script>
  • ✅ console.log(x) 报 ReferenceError → x 未声明;输出 undefined → x 已声明但未初始化;
  • ✅ 优先使用 const / let:更安全、语义清晰、避免 TDZ 外的意外行为;
  • ✅ 避免依赖提升编写逻辑;始终遵循“先声明,后使用”原则;
  • ✅ 大型项目建议采用 ES 模块(type="module")+ 显式导入导出,实现可控的变量共享与作用域管理。

理解作用域边界与提升机制,是写出健壮、可维护 JavaScript 代码的基础。

Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
c语言const用法
c语言const用法

const是关键字,可以用于声明常量、函数参数中的const修饰符、const修饰函数返回值、const修饰指针。详细介绍:1、声明常量,const关键字可用于声明常量,常量的值在程序运行期间不可修改,常量可以是基本数据类型,如整数、浮点数、字符等,也可是自定义的数据类型;2、函数参数中的const修饰符,const关键字可用于函数的参数中,表示该参数在函数内部不可修改等等。

2023.09.20

2478

7

console接口是干嘛的
console接口是干嘛的

console接口是一种用于在计算机命令行或浏览器开发工具中输出信息的工具,提供了一种简单的方式来记录和查看应用程序的输出结果和调试信息。本专题为大家提供console接口相关的各种文章、以及下载和课程。

2023.08.08

956

5

console.log是什么
console.log是什么

console.log 是 javascript 函数,用于在浏览器控制台中输出信息,便于调试和故障排除。想了解更多console.log的相关内容,可以阅读本专题下面的文章。

2024.05.29

7143

7

undefined是什么
undefined是什么

undefined是代表一个值或变量不存在或未定义的状态。它可以作为默认值来判断一个变量是否已经被赋值,也可以用于设置默认参数值。尽管在不同的编程语言中,undefined可能具有不同的含义和用法,但理解undefined的概念可以帮助我们更好地理解和编写程序。本专题为大家提供undefined相关的各种文章、以及下载和课程。

2023.07.31

12385

4

网页undefined是什么意思
网页undefined是什么意思

网页undefined是指页面出现了未知错误的意思,提示undefined一般是在开发网站的时候定义不正确或是转换不正确,或是找不到定义才会提示undefined未定义这个错误。想了解更多的相关内容,可以阅读本专题下面的文章。

2024.08.14

5547

7

网页undefined啥意思
网页undefined啥意思

本专题整合了undefined相关内容,阅读下面的文章了解更多详细内容。后续继续更新。

2025.12.25

2516

7

Go-Zero API开发使用教程
Go-Zero API开发使用教程

本专题聚焦Go-Zero的API开发,拆解.api描述文件的语法结构、路由与分组定义、参数绑定与校验规则,说明统一响应体、JWT鉴权、跨域与接口文档生成的落地方式,并给出网关聚合与接口测试的实践建议。

2026.11.12

40

15

Go-Zero安装与goctl环境配置教程
Go-Zero安装与goctl环境配置教程

本专题围绕Go-Zero的安装与工具链配置展开,讲清Go版本要求、goctl安装方式、代理镜像、protoc依赖与环境变量设置,说明多版本共存、升级回退与CI流水线安装的做法,并整理安装阶段的常见报错与验证步骤。

2026.11.12

40

15

Go-Zero零基础入门教程
Go-Zero零基础入门教程

本专题整理Go-Zero的入门知识,从框架定位、环境准备到跑通第一个API服务,讲清目录分层、配置加载、日志与中间件的基本用法,并对比Gin、Kratos的差异,帮助Go开发者建立整体认知,判断它是否适合当前项目。

2026.11.12

20

15

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
WebStorm 官方调试文档
WebStorm 官方调试文档

共0课时 | 0人学习

React 教程
React 教程

共58课时 | 12.5万人学习

TypeScript 教程
TypeScript 教程

共19课时 | 6.8万人学习