ES6 module:导入后未定义的 onclick 函数

IT技术 javascript ecmascript-6 es6-modules
2021-02-09 15:06:35

我正在测试 ES6 module并希望让用户使用onclick以下方法访问一些导入的功能

测试.html:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Module Test</title>
</head>
<body>
    <input type="button" value="click me" onclick="hello();"/>
    <script type="module">import {hello} from "./test.js";</script>
</body>
</html>

测试.js:

export function hello() {console.log("hello");}

当我单击按钮时,开发人员控制台显示:ReferenceError: hello is not defined如何从module导入函数,以便它们可用作 onclick 函数?

我正在使用 Firefox 54.0 并dom.moduleScripts.enabled设置为true.

2个回答

module创建一个范围以避免名称冲突。

要么将您的功能暴露给window对象

import {hello} from './test.js'

window.hello = hello

或用于addEventListener绑定处理程序。演示

<button type="button" id="hello">Click Me</button>
<script type="module">
  import {hello} from './test.js'

  document.querySelector('#hello').addEventListener('click', hello)
</script>
果断采取方案二。在最好的时候处理全局变量是一种痛苦。
2021-03-12 15:06:35

module中的module范围ES6

当您使用以下方式导入脚本时type="module"

<script type="module">import {hello} from "./test.js";</script>

您正在创建一个称为module范围的特定范围。这是module范围相对于其他级别范围的地方。从全局开始,它们是:

  1. 全球范围:在module以外的所有声明的最外层(即不在函数,并constlet不在块)都可以访问来自世界各地的JavaScript运行环境
  2. module作用域:module内的所有声明都限定在该module内。当其他 javascipt 尝试访问这些声明时,它将引发引用错误。
  3. 函数作用域:在函数体内(顶层)声明的所有变量都是函数作用域
  4. 块作用域:letconst变量是块作用域

您收到 referenceError 是因为该hello()函数是在module中声明的,该module是module scoped正如我们之前看到的,module范围内的声明仅在该module内可用,并且您试图在module外使用它。

当我们显式地将它放在window对象时,我们可以在module内部进行全局声明,以便我们可以在module外部使用它。例如:

window.hello = hello;  // putting the hello function as a property on the window object