请有人确认我对ES模块的理解吗?
在javascripts/bar.js
:
var foo = 2;
export function Bar() {}
在index.html
<script>
import { Bar } from 'javascripts/bar';
var b = new Bar(); // Instantiates an instance of Bar.
</script>
在引擎盖下,ES6引擎在评估bar.js
时会加载import { Bar } from 'javascripts/bar';
,并在通过HTTP返回该模块时阻塞?或者在bar.js
?
index.html
由于使用bar.js
关键字加载了import
,bar.js
中的全局变量是作用于该模块的,并且在全局中不可见?
现在,如果我想连接模块,我将继续需要将我的模块包装在IIFE中,以便它们的范围保持不同(或者至少使用构建步骤来实现这一点)?
答案 0 :(得分:5)
在引擎盖下,ES6引擎在评估来自&#39; javascripts / bar&#39 ;;的导入{Bar}时会加载bar.js,并在通过HTTP返回该模块时阻塞?或者在评估index.html中的脚本之前下载了bar.js?
目前还没有正确答案,因为没有关于如何加载模块的规范。 ES2015仅指定模块语法,但运行时如何解释尚未标准化的语法。例如,最终实现的任何加载器规范都不太可能像您一样省略.js
。并且<script>
标签也不太可能允许使用import
。
但是,抛开你所做的任何语法错误,我可以概括地告诉你什么是可能为浏览器加载器标准化。它是后者:在任何脚本执行发生之前,提前确定并下载导入。 (但是,对于Node.js加载器,它可能会阻塞。)
因为bar.js是使用import关键字加载的,bar.js中的全局变量是作用于该模块的,并且不是全局可见的?
这取决于你对全局变量的意思。如果您声明全局,例如window.x = 5
,仍然会改变全局对象。模块不会让单独的全局对象搞乱。
但是,如果你的意思是&#34;意外&#34;像顶级var
或function
声明声明的那些全局变量,答案是模块中的顶级var
和function
声明不会导致全局属性定义。
(请注意,在模块和脚本中,顶级let
和const
声明不会在全局对象上创建属性。)
现在,如果我想连接模块,我将继续需要将我的模块包装在IIFE中,以便它们的范围保持不同(或者至少使用构建步骤来实现这一点)?
如果你想连接模块,你会遇到比你描述的问题更大的问题。例如,import
和export
仅可在顶层使用,而不能在IIFE内使用。模块并不意味着连接,因为这样做是actively harmful to performance给定的现代浏览器和服务器。