最稳妥的做法是将放在闭合标签之前;因浏览器自上而下解析HTML,此位置可确保DOM已加载完成,避免脚本执行时获取不到元素。

script 标签写在哪儿最稳妥?
浏览器解析 HTML 是从上到下顺序执行的。如果把 <script></script> 放在 里又没加 defer 或 async,脚本会立即下载并执行,此时 DOM 还没加载完,document.getElementById 之类操作大概率返回 null。
- 推荐做法:把
<script></script> 放在 闭合标签前
- 次选但可控:放在
里,但必须加 defer 属性(适用于模块化或依赖 DOM 的逻辑)
- 避免直接用
async 加载主业务脚本——它不保证执行顺序,可能 DOM 还没就绪就跑了
<body>
<div id="app"></div>
<script src="main.js"></script>
</body>
内联脚本和外部文件,什么时候该选哪个?
内联脚本(<script>console.log('hi');</script>)适合极小量、与当前页面强绑定的初始化逻辑,比如埋点 ID、页面级配置。但它无法被浏览器缓存,每次 HTML 加载都得重新传输。
<script></script> 放在 闭合标签前 里,但必须加 defer 属性(适用于模块化或依赖 DOM 的逻辑) async 加载主业务脚本——它不保证执行顺序,可能 DOM 还没就绪就跑了 <script>console.log('hi');</script>)适合极小量、与当前页面强绑定的初始化逻辑,比如埋点 ID、页面级配置。但它无法被浏览器缓存,每次 HTML 加载都得重新传输。
外部文件(<script src="app.js"></script>)才是常规选择:
- 脚本能被缓存,复用率高
- 便于压缩、打包、 sourcemap 调试
- 不污染 HTML 结构,多人协作时更清晰
- 注意路径:如果
index.html和app.js不在同一目录,要用相对路径如./js/app.js或绝对路径/static/js/app.js
ES Module 怎么引用?要注意什么?
想用 import / export,必须显式声明 type="module":
<script type="module" src="main.js"></script>
否则浏览器会报错:Unexpected token 'export' 或 Cannot use import statement outside a module。
几个硬性限制:
- 模块脚本默认是
defer行为(按顺序、DOM 解析完再执行) - 不能省略文件后缀,
import utils from './utils'❌,必须写import utils from './utils.js' - 模块内的顶层
this是undefined,不是window - 本地双击打开
index.html(即file://协议)时,模块导入会因 CORS 被浏览器拦截,必须起一个本地服务(如npx serve)
常见错误:脚本没反应,先查这三件事
脚本“写了但没跑”,90% 出在基础链路上:
- 控制台是否报 404?检查 src 路径拼写、大小写、文件是否真在那个位置
- 是否误用了 type="module" 但脚本里没写 import/export,又没配构建工具?这时浏览器会静默忽略脚本
- 是否在非模块脚本里用了 import,或者在模块脚本里用了 var 声明全局变量却期望在其他地方访问?模块作用域是封闭的,window.xxx = 1 才能挂到全局
路径、协议、模块类型,这三个点卡住就什么都动不了。
立即学习“Java免费学习笔记(深入)”;


















