同一HTML页面中多个script标签间变量函数默认共享,但仅限于顶层var/function声明挂载到全局作用域,let/const及局部变量不可跨块访问,执行顺序即编译顺序,需避免隐式覆盖与TDZ错误。

在同一个 HTML 页面里,多个 <script> 标签之间**变量和函数默认是共享的**,但这种共享有明确的执行顺序和作用域边界——不是“自动互通”,而是“按顺序累积到全局作用域”。理解这一点,就能避开常见报错(如 undefined、not defined)和意外交互。
变量和函数按顺序进入全局作用域
浏览器逐个解析 <script> 块,每个块内的顶层声明(var、function 声明)会提升并挂载到全局对象(window),因此后一个 script 可以读取前一个 script 中定义的全局变量或函数。
-
var声明的变量具有变量提升(hoisting),即使写在 script 底部,也能被同 script 内上方代码访问 -
function声明同样会被提升,整个 script 块内都可调用 - 但
let/const不提升,且存在暂时性死区(TDZ),只在声明之后才可访问 - 后一个 script 无法访问前一个 script 中的
let/const或函数内var局部变量
常见陷阱:你以为能用,其实不能
最容易出错的是误以为两个 script 块像一个文件那样“无缝衔接”——实际它们是独立编译单元,只是共享同一全局环境。典型问题包括:
将调研报告、方案对比、数据分析、需求梳理、会议纪要、设计说明、代码评审、学习笔记等任务产物输出为可在浏览器直接打开的单文件 HTML,替代 Markdown 作为最终交付物。Markdown 在信息密度、视觉清晰度和可分享性上已跟不上 AI 产物的丰富度,HTML 能同时承载排版、表格、SVG 等。
- 在第一个 script 中用
let config = {…},第二个 script 直接写console.log(config)→ 报ReferenceError - 第一个 script 定义了
function init() {…},第二个 script 调用init()没问题;但如果第一个 script 里写的是const init = () => {},且 script 执行顺序颠倒,就可能失败 - 多个 script 都定义
var utils = {...},后者会直接覆盖前者,造成静默逻辑错误
安全共享数据的推荐方式
如果确实需要跨 script 传递配置或工具,不依赖隐式全局,而是采用显式、可控的方式:
立即学习“前端免费学习笔记(深入)”;
- 统一挂载到
window:比如window.APP_CONFIG = { apiBase: '/api' },所有 script 都通过window.APP_CONFIG读取 - 使用模块化(
type="module"):每个 script 是独立模块作用域,需显式export/import,彻底隔离 - 封装命名空间对象:如
window.MyApp = window.MyApp || {},再往里面加属性,避免直接覆盖 - 用
defer或DOMContentLoaded确保执行时机一致,防止因 DOM 或依赖未就绪导致的引用失败
想彻底隔离?用 IIFE 或模块
若不想任何变量泄漏到全局,最稳妥的做法是主动创建私有作用域:
- IIFE(立即执行函数表达式):
(function() { let privateVar = 'safe'; console.log(privateVar); })();—— 里面的let完全不可见于其他 script - ES 模块(
<script type="module">):天然块级作用域,export才暴露,import才引入,适合现代项目 - 注意:
type="module"和普通 script 不共享变量,哪怕都在同一个页面,也完全隔离


















