You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

动态加载外部JS文件后如何正确获取全局类实例及调用类方法

动态加载外部JS文件后如何正确获取全局类实例及调用类方法

嘿,你的问题核心其实是没搞懂动态加载脚本的异步特性——你写的同步代码会比Promise的then回调先执行,这时候脚本还没加载完,类和实例自然都不存在,所以才会报错。我来给你拆解问题并给出具体的解决办法:

先说说你遇到的两个错误原因

  1. 为什么var appi = new Application()会报错?
    因为injectScript是异步执行的,它返回的Promise会在脚本加载完成后才触发then,但你写的var appi = new Application()是同步代码,会在脚本开始加载但还没加载完成时就运行,这时候Application类根本还没被定义,自然会提示“类未定义”。

  2. 为什么后面的app.showText()会报错?
    同样的道理,这个同步代码会比then里的app = new Application()先执行,此时app还是你一开始声明的undefined,当然没有showText方法。

解决方案一:用async/await让逻辑更清晰(推荐)

把所有依赖加载后代码放到async函数里,用await等待脚本加载完成,这样代码逻辑就像同步一样,但实际是异步执行的:

/* 加载外部JS的函数保持不变 */
function injectScript(src) {
    return new Promise((resolve, reject) => {
        const script = document.createElement('script');
        script.src = src;
        script.addEventListener('load', resolve);
        script.addEventListener('error', e => reject(e.error));
        document.head.appendChild(script);
    });
}

/* 用async函数封装初始化逻辑 */
async function initApplication() {
    try {
        // 等待脚本加载完成,这一步完成后Application类才会被定义
        await injectScript('application.js');
        
        // 实例化并挂载到window上,让全局都能访问
        window.app = new Application();
        
        // 现在可以正常调用方法了
        app.showText();
        
        // 这里也能正常实例化新的对象
        const appi = new Application();
        appi.showText();
    } catch (error) {
        console.error('加载脚本时出错:', error);
    }
}

// 启动初始化
initApplication();

解决方案二:如果需要在其他代码块调用,用自定义事件通知

如果你的代码分散在不同地方,不想都塞进一个async函数,可以用自定义事件来通知“App已经准备好”,其他地方监听这个事件再执行代码:

async function initApplication() {
    try {
        await injectScript('application.js');
        window.app = new Application();
        // 触发自定义事件,告诉其他代码App已就绪
        document.dispatchEvent(new CustomEvent('appReady'));
    } catch (error) {
        console.error(error);
    }
}

initApplication();

// 在需要调用的地方监听事件
document.addEventListener('appReady', () => {
    // 现在app已经存在,可以正常调用方法
    app.showText();
    
    // 也能正常实例化Application类
    const appi = new Application();
    appi.showText();
});

关键要点总结

  • 动态加载脚本是异步操作,所有依赖这个脚本的代码必须等待加载完成后才能执行,不能直接写在加载代码的后面(同步执行)。
  • 如果需要全局访问实例,把实例挂载到window对象上是最简单的方式(当然你也可以用模块化方案,但你说不想用服务器,所以全局挂载最直接)。
  • 跨代码块的依赖调用,用自定义事件或者Promise链式调用都是可靠的方式,核心就是等待加载完成的信号再执行后续代码。

备注:内容来源于stack exchange,提问作者Orbit

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.14 13:07:59