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

跨模块调用函数时遭遇Uncaught ReferenceError错误求助

问题:模块变量未初始化导致的引用错误

模块代码

database.js

import { initializeApp } from "https://www.gstatic.com/firebasejs/9.15.0/firebase-app.js";
import { getFirestore, collection, getDocs } from "https://www.gstatic.com/firebasejs/9.15.0/firebase-firestore-lite.js";
import { getAuth } from "https://www.gstatic.com/firebasejs/9.15.0/firebase-auth.js";

const firebaseConfig = {
  // 配置信息
};

// 初始化Firebase
const app = initializeApp(firebaseConfig);
const auth = getAuth(app);

const db = getFirestore(app);

let usersListTmp = [];

async function getUsersListFromDB() {
    if (usersListTmp.length == 0) { // 此处报错!
        await getDocs(collection(db, "users")).then((usersSnapshot) => {
            usersSnapshot.forEach((value) => {
                usersListTmp.push(value.data());
            });
        });
    }
    return usersListTmp;
}

export {
    getUsersListFromDB
}

common.js

import { getUsersListFromDB } from "../database/database.js";

let usersList = await getUsersListFromDB(); // 此处调用函数
console.log(usersList);

function getUsersList() {
    return usersList;
}

function setUsersList(list) {
    usersList = list;
}

export {
    getUsersList,
    setUsersList
}

input_data.js

import { registerUser, getUsersListFromDB } from "../database/database.js";
import { getUsersList } from "../js/common.js"

let usersList = getUsersList(); // 此处为初始函数调用
console.log(usersList);

错误信息

在common.js调用getUsersListFromDB()时触发:

Uncaught ReferenceError: can't access lexical declaration 'usersListTmp' before initialization

调整代码后,firebaseConfig、app、auth、db也出现相同的未初始化错误。

补充:全局变量均未初始化,仅在函数调用时执行函数逻辑,未完成全局变量初始化。

需求

保证usersListTmp仅在database.js模块内访问,同时解决变量未初始化的错误。


解决方案

1. 修复顶级await导致的执行顺序问题

common.js中的顶级await会阻塞模块加载,可能导致database.js未完成变量初始化就被调用。将初始化逻辑封装到异步函数中:

import { getUsersListFromDB } from "../database/database.js";

let usersList = [];

async function initUsersList() {
    usersList = await getUsersListFromDB();
    console.log(usersList);
}

initUsersList();

function getUsersList() {
    return usersList;
}

function setUsersList(list) {
    usersList = list;
}

export {
    getUsersList,
    setUsersList,
    initUsersList // 可选:导出初始化函数,供主模块等待加载完成
}

2. 封装私有变量确保初始化顺序

用IIFE封装usersListTmp,既保证变量私有,又确保初始化逻辑优先执行:

import { initializeApp } from "https://www.gstatic.com/firebasejs/9.15.0/firebase-app.js";
import { getFirestore, collection, getDocs } from "https://www.gstatic.com/firebasejs/9.15.0/firebase-firestore-lite.js";
import { getAuth } from "https://www.gstatic.com/firebasejs/9.15.0/firebase-auth.js";

const firebaseConfig = {
  // 配置信息
};

// 初始化Firebase实例
const app = initializeApp(firebaseConfig);
const auth = getAuth(app);
const db = getFirestore(app);

// IIFE封装私有变量和函数,确保变量先初始化再被访问
const getUsersListFromDB = (() => {
    let usersListTmp = [];

    return async function() {
        if (usersListTmp.length === 0) {
            // 替换then为await,简化代码逻辑
            const usersSnapshot = await getDocs(collection(db, "users"));
            usersSnapshot.forEach((value) => {
                usersListTmp.push(value.data());
            });
        }
        return usersListTmp;
    };
})();

export {
    getUsersListFromDB
}

3. 主模块等待初始化完成

若需要确保usersList加载完成后再使用,在input_data.js中等待初始化:

import { getUsersList, initUsersList } from "../js/common.js"

async function main() {
    await initUsersList();
    let usersList = getUsersList();
    console.log(usersList);
}

main();

错误原因

  • 顶级await会让模块进入等待状态,打乱依赖模块的初始化顺序,导致函数访问变量时变量未完成初始化。
  • 模块加载的执行顺序因顶级await被干扰,触发“无法在初始化前访问词法声明”的错误。

内容的提问来源于stack exchange,提问作者Al-Jaabir

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 03:53:22