ES6模块:导入后未定义的onclick功能

时间:2017-06-16 13:24:08

标签: javascript ecmascript-6 es6-modules

我正在测试ES6模块,并希望让用户使用onclick访问一些导入的函数:

的test.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>

test.js:

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

当我单击按钮时,开发人员控制台会说: ReferenceError:未定义hello 。如何从模块导入函数以使它们可用作onclick函数?

我使用的是Firefox 54.0,dom.moduleScripts.enabled设置为true

2 个答案:

答案 0 :(得分:24)

模块创建范围以避免名称冲突。

将您的函数公开给window对象

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

window.hello = hello

或使用addEventListener来绑定处理程序。 Demo

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

  document.querySelector('#hello').addEventListener('click', hello)
</script>

答案 1 :(得分:1)

ES6模块中的模块作用域:

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

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

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

  1. 全局范围:在模块最外层(即,不在函数中,并且对于constlet不在块中)的所有声明都可以在Javascript运行时环境中的任何位置进行访问< / li>
  2. 模块作用域:模块内部的所有声明都作用于该模块。当其他javascipt尝试访问这些声明时,它将引发引用错误。
  3. 函数作用域:在函数主体内部(顶层)声明的所有变量都在函数作用域之内
  4. 块作用域:letconst变量是块作用域

您收到referenceError是因为在模块中声明了hello()函数,该函数是模块作用域的。如我们所见,模块作用域内的较早声明仅在该模块内可用,并且您尝试将其使用在模块之外。

当我们明确将其放在 window 对象上时,我们可以在模块内部进行全局声明,以便可以在模块外部使用它。例如:

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