我正在尝试使用 Chrome v65
的一些 ES6
功能
我有以下文件:
base.js :
export function consoleLogger(message) {
console.log(message);
}
main.js
import { consoleLogger } from './base.js';
consoleLogger('Some message');
utils.js
function sayMyName(name) {
console.log(name);
}
imports.html
<!DOCTYPE html>
<html>
<head>
<script src='./main.js' type='module'></script>
<script src='./utils.js'></script>
</head>
<body>
<script>
sayMyName('Cool name');
</script>
</body>
</html>
像这样使用一切似乎都很好,在控制台中我得到了
Cool name utils.js:2
Some message base.js:2
然而,让我们想象一下我需要一些额外数据以便为 consoleLogger
方法编写消息的场景。然后我想在 main.js
function logToConsole(msg) {
consoleLogger(msg);
}
并且在imports.html
<script>
sayMyName('Cool name');
logToConsole('Send from log to console');
</script>
然后对于 logToConsole('Send from log to console');
在控制台中调用我的 html
文件,我得到:
Uncaught ReferenceError: logToConsole is not defined at imports.html:10
所以从base.js
导入consoleLogger
没有问题,直接在main.js
中调用,就没有问题包含另一个 .js 文件 (utils.js
) 并从那里调用方法,但是如果我尝试调用在 main.js
中声明的方法,它在内部调用导入的方法我从上面得到了错误。看起来 main.js
中的方法是否引用导入的方法似乎并不重要。我只是注释了所有内容,只留下一个简单的方法
main.js
import { consoleLogger } from './base.js';
/*function logToConsole(msg) {
consoleLogger(msg);
}
consoleLogger('Some message');*/
function randomStuff() {
console.log('random stuff');
}
在控制台中我得到了这个错误:
imports.html:11 Uncaught ReferenceError: randomStuff is not defined at imports.html:11
有人可以向我解释这种行为的原因吗?
最佳答案
ES 模块(和一般的 JS 模块)的目的之一是防止全局范围的污染。
模块导出不应该泄漏到全局范围。模块的使用通常假定所有第一方代码都驻留在模块中。 logToConsole('Send from log to console')
转到主模块。
如果需要与全局范围进行互操作,则应在模块内将变量显式公开为全局变量:
window.logToConsole = function (msg) {
consoleLogger(msg);
}
正如另一个答案已经提到的,仍然可能存在竞争条件,因为模块是异步加载的。脚本应推迟到文档准备就绪 - jQuery ready
事件或 native 对应事件:
<script>
document.addEventListener('DOMContentLoaded', () => {
logToConsole('Send from log to console');
});
<script>
关于javascript - 从 html 文件访问导出的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50176213/