处理脚本依赖关系应明确执行顺序:用defer保证外部脚本按序执行且dom就绪;动态加载时用$script.js或loadjs管理依赖;手动插入需监听onload/onerror并防重复;避免settimeout轮询、盲目放body前或混用async/defer。

处理脚本依赖关系的关键不是“等它加载完再试”,而是让浏览器或加载器明确知道“谁必须先于谁执行”。用错方式(比如乱加 async)反而会破坏顺序、引发 ReferenceError 或 document.getElementById is null 这类错误。
用 defer 保证顺序,最简单可靠
这是 HTML 原生支持、兼容性好、无需额外库的方案:
-
只适用于外部脚本(
src属性存在),内联脚本加defer会被忽略 - 多个
defer脚本按书写顺序执行,DOM 构建完成、DOMContentLoaded触发前运行,document.getElementById一定可用 - 适合 jQuery + 插件 + 业务逻辑这类强依赖链
示例写法:
<script defer src="jquery.min.js"></script><script defer src="chart.js"></script>
<script defer src="app.js"></script>
用 $script.js 或 LoadJS 管理动态依赖
当脚本需按条件加载、或在运行时决定加载哪些资源时,轻量加载器更灵活:
-
$script.js:用 ID 标识脚本,用
$script.ready('id', callback)等待就绪 -
LoadJS:用
ordered = true参数强制串行执行,如loadJS('lib.js', true)→loadJS('plugin.js', true) - 两者都支持回调,在加载完成后安全调用函数,避免
xxx is not defined
典型场景:用户点击“报表”按钮后,才加载 ECharts 并初始化图表。
动态插入 script 时必须显式监听 onload
手动创建 <script></script> 元素默认行为接近 async=true,不能插完就调函数:
-
onload 必须在设置
src之后立即绑定,否则可能错过回调 - 务必配
onerror,否则 404 静默失败,调试无从下手 - 插入前检查是否已加载(如
if (!window.jQuery)),避免重复请求
正确写法示例:
const s = document.createElement('script');s.src = 'https://cdn.example.com/jquery.min.js';
s.onload = () => { initApp(); };
s.onerror = () => console.error('jQuery 加载失败');
document.head.appendChild(s);
避开常见陷阱
这些做法看似能“绕过问题”,实则掩盖本质、增加维护成本:
- 不用
setTimeout轮询检查变量是否存在 —— 不稳定、浪费性能、不可靠 - 不靠“把 script 放到











