如何使用 JavaScript 动态加载并执行脚本

作者:袖梨 2026-07-15
JavaScript动态加载脚本主要有三种方式:一是用document.createElement('script')插入DOM,兼容性好,支持错误处理;二是ES模块的import(),支持按需加载和tree-shaking;三是fetch+Function执行字符串代码,仅限可信源。

JavaScript 动态加载与执行脚本,核心是通过创建 <script> 元素并插入 DOM,或使用现代 API(如 import())按需获取和运行代码。关键在于控制加载时机、处理依赖、捕获错误,并避免重复执行或阻塞渲染。

document.createElement('script') 动态插入

这是最通用、兼容性最好的方式,适用于任何 JS 文件(本地或 CDN),支持回调与错误处理。

  • 创建 script 元素,设置 src 属性指向目标文件路径
  • 可选:设置 async = true(默认行为)让脚本异步加载不阻塞 HTML 解析;设 defer = true 可保证执行顺序(仅对同域脚本有效,且需在 <head> 中插入)
  • 监听 load 事件表示加载成功并已执行;监听 error 事件捕获 404、跨域等失败情况
  • 插入到 document.headdocument.body 即可触发加载

示例:

function loadScript(src) {  return new Promise((resolve, reject) => {    const script = document.createElement('script');    script.src = src;    script.async = true;    script.onload = () => resolve(script);    script.onerror = () => reject(new Error(`Failed to load ${src}`));    document.head.appendChild(script);  });}// 使用loadScript('/js/utils.js')  .then(() => console.log('utils.js loaded'))  .catch(err => console.error(err));

import() 动态导入模块(ES Module)

适用于现代浏览器和打包工具(如 Webpack、Vite),支持真正的按需加载、tree-shaking 和静态分析,返回 Promise,天然支持 await。

立即学习“Java免费学习笔记(深入)”;

  • 只能加载符合 ES 模块规范的文件(type="module" 脚本或后缀为 .mjs 的文件)
  • 路径必须是字符串字面量或模板字符串(不能是拼接变量,否则打包工具无法解析)
  • 导入后可直接使用导出的函数、类或值,无需额外执行逻辑
  • 自动处理依赖关系,重复调用同一路径会复用已解析模块

示例:

// utils.js 导出:export function formatDate(date) { ... }// 动态加载并使用async function init() {  const { formatDate } = await import('./utils.js');  console.log(formatDate(new Date()));}

手动执行内联或远程脚本内容

当需要加载纯代码字符串(比如从 API 获取 JS 片段),或绕过 CORS 限制(但有安全风险),可用 evalFunction 构造器。⚠️ 不推荐用于不可信来源。

  • fetch 获取脚本文本,再用 new Function(code)() 执行(比 eval 更安全,作用域隔离)
  • 注意:动态执行的代码无法访问当前作用域的变量(除非显式传参),调试也较困难
  • 若脚本含 import/export,不能直接执行,需先转为模块或改用 import()

示例(仅限可信上下文):

async function executeScript(url) {  const res = await fetch(url);  const code = await res.text();  new Function(code)();}

注意事项与最佳实践

动态加载不是“万能补丁”,需结合场景谨慎使用。

  • 避免在循环中无节制地加载相同脚本——应缓存 Promise 或检查 document.querySelector(`script[src="${src}"]`) 是否已存在
  • 第三方脚本(如统计、埋点)建议加超时控制,防止因网络问题阻塞后续逻辑
  • 服务端渲染(SSR)环境下,document 未定义,需加判断:if (typeof document !== 'undefined') { ... }
  • 调试时可通过浏览器 DevTools 的 “Network” 面板确认脚本是否发起请求,“Sources” 面板查看是否成功加载和执行

相关文章

精彩推荐