函数触发后导出变量为undefined问题求助
问题:导出点击事件赋值的变量后,导入始终为undefined
我声明了全局作用域的空变量,通过函数捕获被点击链接的id并赋值给该变量,需要将此变量导出到另一个脚本,但导入后变量始终为undefined。尝试过导出带返回值的函数,但导入的是整个函数,无法获取目标值。
导出变量的脚本(noticias.js)
var objetoApiClicado; var noticias = []; fetch("https://api-kwi5.onrender.com/v1/api/noticias") .then((response) => response.json()) .then((data) => { noticias = data.response; console.log(noticias); openNoticias(noticias); }) .catch((erro) => { console.log(erro) }) function openNoticias(noticias) { const btnNoticiasId = document.querySelectorAll('[data-id]'); btnNoticiasId.forEach(e => { e.addEventListener("click", event => { event.preventDefault(); console.log(e.parentNode); idNoticia = e.getAttribute('data-id'); console.log(idNoticia); objetoApiClicado = noticias.find(noticia => noticia.id == idNoticia); console.log(objetoApiClicado); }); }); } export { idNoticia, objetoApiClicado }
导入变量的脚本
import {idNoticia , objetoApiClicado} from "./noticias.js"; var noticia = [ ]; async function verificaId() { const conexao = await fetch(`https://api-kwi5.onrender.com/v1/api/noticias`); const noticiasResponse = await conexao.json(); noticia = noticiasResponse.response; console.log(noticia) let id = idNoticias; // 拼写错误:应为idNoticia const comparaId = noticia.find(noticia => noticia.id == parseInt(id)); console.log(comparaId); exibirBanner(comparaId) exibirNoticias(comparaId) } function exibirBanner(noticia) { const bannerSection = document.querySelector('.banner__postagem--container'); bannerSection.innerHTML += ` <div class="banner__postagem--conteudo"> <h2 class="banner__postagem--titulo">${noticia.titulo}</h2> <p class="banner__postagem--data">Julho 7, 2023 Notícia</p> </div> ` }; function exibirNoticias(noticias) { const noticiaSection = document.querySelector('.postagem__container'); noticiaSection.innerHTML += ` <div class="postagem__container--conteudo"> <img src="data:image/png;base64,${noticias.file}" alt="Dentista mostrando 4 mitos dos implante dentarios" class="postagem__imagem"> <p class="postagem__texto">${noticias.conteudo}</p> </div>` }
问题原因分析
- 变量未声明:
idNoticia未用var/let/const声明,属于隐式全局变量,导出时存在绑定异常。 - 异步时机错配:点击事件是用户触发的异步操作,导入脚本加载时,目标变量仍为初始
undefined,若verificaId在点击前执行,自然拿不到值。 - 拼写错误:导入脚本中
idNoticias是笔误,直接导致id为undefined。 - 原始类型绑定限制:即使修正声明,
idNoticia是原始类型(字符串),ES模块导出的绑定仅在变量实时读取时生效,若导入脚本提前读取,后续赋值无法同步。
解决方案
方案1:自定义事件传递数据(推荐)
通过自定义事件在点击触发时传递数据,符合前端事件驱动逻辑,代码解耦性更强。
修改导出脚本:
var noticias = []; fetch("https://api-kwi5.onrender.com/v1/api/noticias") .then((response) => response.json()) .then((data) => { noticias = data.response; openNoticias(noticias); }) .catch((erro) => console.log(erro)) function openNoticias(noticias) { const btnNoticiasId = document.querySelectorAll('[data-id]'); btnNoticiasId.forEach(e => { e.addEventListener("click", event => { event.preventDefault(); const idNoticia = e.getAttribute('data-id'); const objetoApiClicado = noticias.find(noticia => noticia.id == idNoticia); // 触发自定义事件传递数据 window.dispatchEvent(new CustomEvent('noticiaClicada', { detail: { idNoticia, objetoApiClicado } })); }); }); }
修改导入脚本:
var noticia = []; async function carregarNoticias() { const conexao = await fetch(`https://api-kwi5.onrender.com/v1/api/noticias`); const noticiasResponse = await conexao.json(); noticia = noticiasResponse.response; } // 提前加载新闻数据 carregarNoticias(); // 监听自定义事件获取点击数据 window.addEventListener('noticiaClicada', (event) => { const { objetoApiClicado } = event.detail; exibirBanner(objetoApiClicado); exibirNoticias(objetoApiClicado); }); function exibirBanner(noticia) { const bannerSection = document.querySelector('.banner__postagem--container'); bannerSection.innerHTML = ` <div class="banner__postagem--conteudo"> <h2 class="banner__postagem--titulo">${noticia.titulo}</h2> <p class="banner__postagem--data">Julho 7, 2023 Notícia</p> </div> `; } function exibirNoticias(noticias) { const noticiaSection = document.querySelector('.postagem__container'); noticiaSection.innerHTML = ` <div class="postagem__container--conteudo"> <img src="data:image/png;base64,${noticias.file}" alt="Dentista mostrando 4 mitos dos implante dentarios" class="postagem__imagem"> <p class="postagem__texto">${noticias.conteudo}</p> </div>`; }
方案2:导出状态对象(引用类型)
利用对象的引用特性,修改对象属性会同步到所有引用位置,避免原始类型的绑定问题。
修改导出脚本:
// 用对象统一保存状态 export const estadoNoticia = { idNoticia: undefined, objetoApiClicado: undefined }; var noticias = []; fetch("https://api-kwi5.onrender.com/v1/api/noticias") .then((response) => response.json()) .then((data) => { noticias = data.response; openNoticias(noticias); }) .catch((erro) => console.log(erro)) function openNoticias(noticias) { const btnNoticiasId = document.querySelectorAll('[data-id]'); btnNoticiasId.forEach(e => { e.addEventListener("click", event => { event.preventDefault(); estadoNoticia.idNoticia = e.getAttribute('data-id'); estadoNoticia.objetoApiClicado = noticias.find(noticia => noticia.id == estadoNoticia.idNoticia); }); }); }
修改导入脚本:
import { estadoNoticia } from "./noticias.js"; var noticia = []; async function carregarNoticias() { const conexao = await fetch(`https://api-kwi5.onrender.com/v1/api/noticias`); const noticiasResponse = await conexao.json(); noticia = noticiasResponse.response; } carregarNoticias(); // 确保在点击后调用该函数(比如绑定到按钮事件或监听状态变化) function verificaId() { if (!estadoNoticia.idNoticia) return; const comparaId = noticia.find(noticia => noticia.id == parseInt(estadoNoticia.idNoticia)); exibirBanner(comparaId); exibirNoticias(comparaId); }
注意事项
- 所有变量必须用
let/const/var声明,禁止隐式全局变量。 - 异步操作的执行时机要明确,避免在异步完成前读取依赖值。
- 优先使用自定义事件方案,代码解耦性和可维护性更好。
内容的提问来源于stack exchange,提问作者Gustavo Lopes
相关产品推荐
相关产品推荐

