2016-01-05 96 views
4

我尝试从Mozilla Hacks重复例如(导出列表字幕)之前:出口对象和类的声明使得他们不确定

//export.js 
export {detectCats, Kittydar}; 
function detectCats() {} 
class Kittydar {} 

//import.js 
import {detectCats, Kittydar} from "./export.js"; 
console.log(detectCats); // function detectCats() {} 
console.log(Kittydar); // undefined 

哎呀:Kittydar是不确定的(顺便说一句,这个问题是相同的简单的Object)。

但是,如果我以后Kittydar声明把export它的确定:

//export.js 
class Kittydar {} 
export {Kittydar}; 

//import.js 
import {Kittydar} from "./export.js"; 
console.log(Kittydar); // function Kittydar() {_classCallCheck(this, Kittydar);} 

这是在文章中错字?

我transpile这与babelbrowserify捆绑。然后我在通常的.html文件中包含输出包(使用<script>标签)。

+0

由于没有支持ES6模块的JavaScript环境,我假设您正在使用转换器将ES6模块转换为另一个模块系统。在这种情况下,该转译器似乎不能正确处理类。 AFAIK你应该根据ES6规范工作。 –

+0

嗯......我使用'grunt-babel @ 5.0.1',它使用'babel-core @ 5.8.23'。好吧,我要用纯粹的和最后的'babel'版本来检查它。 – mqklin

+0

@FelixKling,我用最新的'babel @ 6.3.26'和'browserify @ 12.0.1'重复了它。同样的行为。它可能是一个错误? – mqklin

回答

5

的标准是很难遵循这一点,但文章是正确的。此代码适用于es6draft和SpiderMonkey外壳:函数和类在调用console.log调用运行时被初始化。

这里是它如何工作的,在微小的细节:

  • 的JS引擎解析import.js。它看到import声明,然后它加载export.js并解析它。

  • 在实际运行任何代码,系统会创建两个模块范围,并与所有的每个模块中声明的顶级绑定填充它们。 (该规范称为ModuleDeclarationInstantiation。)在export.js中创建了一个Kittydar绑定,但现在尚未初始化。

    在import.js中,创建了一个Kittydar导入绑定。这是export.js中Kittydar绑定的别名。

  • export.js运行。该课程已创建。 Kittydar被初始化。

  • import.js运行。 console.log()调用工作正常。


通天的实施ES6模块是非标准的。

我认为这是经过深思熟虑的。 Babel的目标是将ES6模块编译成适合您选择的现有模块系统的ES5代码:您可以让它淘汰AMD模块,UMD,CommonJS等。因此,如果您要求提供AMD输出,您的代码可能是ES6模块,但是ES5的输出是一个AMD模块,它的行为就像是一个AMD模块。

巴贝尔或许可以更符合标准,同时还与各模块系统整合很好,但也有权衡。