【问题标题】:Access variables declared in dynamically imported JavaScript?访问在动态导入的 JavaScript 中声明的变量?
【发布时间】:2020-05-19 13:19:24
【问题描述】:

我正在开发单页架构 (SPA) Web 应用程序。我已经实现了动态加载应用程序不同页面的功能。

这就是我的 spa.js 的样子

var spa = {
    init: async () => {

        await import('./page.js')
        spa.data['page'].apply()
    },

    register: (page, data) => {
        spa.data[page] = data
    },

    data: {},
}

window.onload = () => {
    spa.init()
}

这就是我的 page.js 的样子

const pageData = {
    apply: () => {
        document.body.innerHTML = getMSG()
    }
}

function getMSG() {
    return "hello message!"
}

spa.register('page', pageData)

工作流程说明:

  • 最初会加载 spa.jsspa.data 为空
  • 它启动 spa.init(),它会加载 page.js
  • page.js 将其数据注册到 spa 变量
  • 现在控制跳回到 spa.jsspa.data 页面,它将执行 apply()

这很好用。但这里有一件奇怪的事情!

apply() 方法可以访问裸 getMSG(),但是当我尝试通过浏览器的开发人员执行 getMSG()控制台我得到 ReferenceError 暗示 getMSG() 根本没有定义!我们的 pageData

也是如此

这里是托管的heroku应用,你可以试试-dyn-import

虽然它非常好,因为我不必担心不同文件中的函数冲突,但我想知道这是怎么发生的。

谁能解释我如何访问 page.js 中定义的方法和变量。我知道出口,但不知何故没有出口!

【问题讨论】:

  • 用控制台执行是什么意思?您希望它可以在全球范围内访问吗?
  • await import('./page.js').then() 很奇怪。要么你await something(),要么你用something().then()去承诺风格。但不是两者都
  • @ThakurKarthik 控制台,我的意思是浏览器控制台(F12,开发者控制台)。当我尝试通过控制台访问该方法时,它显示未定义。但是脚本可以访问它,就好像它是全局的一样。我的问题是它是全球性的吗?如果是,为什么它在控制台中不起作用,如果不是,如何应用方法访问它?

标签: javascript single-page-application dynamic-import


【解决方案1】:

如果模块中定义的函数和变量未导出,则不能直接访问它们。

spa 变量可全局访问的原因是因为 spa.js 是普通脚本,在 HTML 文档头部引用。

<head>
    ...
    <script src="./spa.js"></script>
</head>

另一方面,如果您使用import 脚本,则变量位于不同的范围内,除非您将它们导出。所以 page.js 被视为一个模块

当然,您可以将函数 getMSG() 附加到全局变量 spapageData,但两者都是解决方法。

spa.getMSG = getMSG;

您可以在此处阅读有关模块和标准脚本之间差异的更多信息 - MDN JavaScript modules

【讨论】:

  • 但是在spa.init()中调用apply()函数可以访问getMSG(),它是模块的一部分,不导出。
  • 是的,因为您使用spa.register('page', pageData) 手动将pageData 附加到spa。对函数执行类似操作。例如:spa.getMSG = getMSG.
  • Nenad,即使我没有将 getMSG 附加到 spa,它也能满足我的要求。我的问题更多是关于为什么它在不附加的情况下在 spa 中工作,以及为什么它不在控制台中?
  • 我已经告诉了你一切。您可以将其视为page.js 内部的private 函数。它可以在spa 中工作,因为您将函数包装在pageData.apply 中,然后使用spa.register('page', pageData)pageData 附加到spa。不确定你不清楚什么。
  • 谢谢!现在很清楚了。如果您可以在上面的答案中链接到与导入模块范围相关的一些文档,那将非常有帮助
猜你喜欢
  • 1970-01-01
  • 2019-02-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-14
  • 2017-09-18
相关资源
最近更新 更多