为何跨script标签访问后续变量会报错而非输出undefined?
变量提升与script标签的执行机制问题
问题场景
两段代码表现差异明显:
代码片段1
<script> console.log(x); </script> <script> var x = 10; </script>
执行后控制台报错:Uncaught ReferenceError: x is not defined
代码片段2
<script> console.log(x); var x = 10; </script>
执行后控制台输出:undefined
疑惑点:原本以为同一页面的变量会全局提升,但因为console.log和变量声明分属不同script标签就报错,想知道原因。
原因解析
- 变量提升的作用范围是单个script标签,不是整个页面的全局范围。浏览器会按页面里script标签的顺序逐个处理,每个script标签都是独立的预编译+执行单元。
- 对于代码片段1:第一个script标签执行前,预编译阶段只会扫描当前标签内的代码——这里没有
var x的声明,所以不会做变量提升。执行console.log(x)时,全局作用域里还不存在x(第二个script标签还没被执行,它的变量声明还没生效),因此触发引用错误。 - 对于代码片段2:同一个script标签内,预编译阶段会把
var x的声明提升到当前脚本的最顶部,实际执行顺序相当于:
所以执行var x; // 变量提升,仅声明未赋值 console.log(x); x = 10;console.log(x)时,x已经被声明,只是还没赋值,因此输出undefined。 - 额外说明:第二个script标签执行时,
var x会被提升到该标签顶部,同时作为var声明的变量会挂载到全局对象(比如浏览器的window)上,但这一步是在第一个script执行完成后才发生的,所以第一个script完全感知不到这个变量。
内容的提问来源于stack exchange,提问作者Mahmoud Fathy
相关产品推荐
相关产品推荐

