是否提升了ES6模块的进口?

时间:2015-03-29 13:26:01

标签: javascript ecmascript-6 hoisting es6-modules

我知道在新的ES6模块语法中,JavaScript引擎不必评估代码来了解所有导入/导出,它只会解析它并“知道”要加载什么。

这听起来像是在吊装。 ES6模块是否悬挂?如果是这样,在运行代码之前它们都会被加载吗?

这段代码可以吗?

import myFunc1 from 'externalModule1';

myFunc2();

if (Math.random()>0.5) {
    import myFunc2 from 'externalModule2';
}

3 个答案:

答案 0 :(得分:24)

这将是一个SyntaxError 。根据{{​​3}}:

Module :
   ModuleBody

ModuleBody :
    ModuleItemList

ModuleItemList :
    ModuleItem
    ModuleItemList ModuleItem

ModuleItem :
    ImportDeclaration
    ExportDeclaration
    StatementListItem

这意味着该模块只能包含ImportDeclarationExportDeclarationStatementListItem。 根据{{​​3}} StatementListItem可以 不包含ImportDeclarationExportDeclaration

import myFunc1 from 'externalModule1'; 

是一个导入声明,而:

if (Math.random()>0.5) {
    import myFunc2 from 'externalModule2';
}

是一份声明。因此,您的代码将导致语法错误。

“在运行代码之前它们都会被加载吗?” this part of specification包含下一句话:

  

注意:在实例化模块之前,它所请求的所有模块都必须可用。

所以,是的。 在运行代码之前将全部加载

答案 1 :(得分:23)

在做了一些研究后,我发现:

  • 进口货物悬挂!根据 ModuleDeclarationInstantiation
  • spec
  • 在运行任何代码之前,将加载所有相关模块。

此代码没有错误,并且可以正常工作:

localFunc();

import {myFunc1} from 'mymodule';

function localFunc() { // localFunc is hoisted
    myFunc1();
}

答案 2 :(得分:3)

ES6规范是一个需要改变的主题,但this draft是明确的:

  

静态变量解析和链接传递检查冲突   在导入的变量名称中。如果两者之间存在冲突   导入的名称,或导入的名称和另一个本地绑定,然后它   是一个编译时错误。

尝试在运行时导入是一个值得怀疑的想法,不仅仅是在ES6中。也来自草案:

  

编译解析并验证所有变量定义和   引用。链接也发生在编译时;链接解决方案和   验证所有模块导入和导出。

您可以看到Babel's ES6 implementation对此并不满意。