Ecmascript 6 在对象和类的声明使其未定义之前导出它们

Ecmascript 6 在对象和类的声明使其未定义之前导出它们,ecmascript-6,babeljs,Ecmascript 6,Babeljs,我尝试重复(导出列表副标题)中的示例: Oops:Kittydar未定义(顺便说一句,问题与simple对象的问题相同) 但是如果我把export放在Kittydar声明之后,就可以了: //export.js class Kittydar {} export {Kittydar}; //import.js import {Kittydar} from "./export.js"; console.log(Kittydar); // function Kittydar() {_classCal

我尝试重复(导出列表副标题)中的示例:

Oops:Kittydar未定义(顺便说一句,问题与simple
对象的问题相同)

但是如果我把
export
放在
Kittydar
声明之后,就可以了:

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

//import.js
import {Kittydar} from "./export.js";
console.log(Kittydar); // function Kittydar() {_classCallCheck(this, Kittydar);}
这篇文章是打字错误吗


我使用
babel
传输此文件,并使用
browserify
进行捆绑。然后我将输出包包括在一个普通的
.html
文件中(带有
标记)。

这个标准很难遵循,但是这篇文章是正确的。这段代码在SpiderMonkey shell中工作:函数和类都在运行这些
console.log
调用时初始化

下面是它的工作原理,非常详细:

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

  • 在实际运行任何代码之前,系统将创建两个模块作用域,并使用每个模块中声明的所有顶级绑定填充它们。(规范称之为)在export.js中创建了
    Kittydar
    绑定,但目前尚未初始化

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

  • export.js运行。类被创建<代码>Kittydar
已初始化

  • import.js运行。两个
    console.log()
    调用都可以正常工作


  • 巴贝尔对ES6模块的实施是非标准的。

    我认为这是故意的。Babel的目标是将ES6模块编译成ES5代码,与您选择的现有模块系统一起工作:您可以让它吐出AMD模块、UMD、CommonJS等。因此,如果您要求AMD输出,您的代码可能是ES6模块,但ES5输出是AMD模块,它的行为将类似于AMD模块


    Babel可能更符合标准,但仍能很好地与各种模块系统集成,但有一些折衷。

    由于没有支持ES6模块的JavaScript环境,我假设您正在使用transpiler将ES6模块转换为另一个模块系统。在这种情况下,transpiler似乎不能正确处理类。好吧,你所拥有的应该是符合ES6规范的。。。我使用
    grunt-babel@5.0.1
    哪个使用了
    巴别塔-core@5.8.23
    。好的,我将用pure和last
    babel
    版本检查它。@FelixKling,我用last
    babel@6.3.26
    browserify@12.0.1
    。同样的行为。会是虫子吗?
    //export.js
    class Kittydar {}
    export {Kittydar};
    
    //import.js
    import {Kittydar} from "./export.js";
    console.log(Kittydar); // function Kittydar() {_classCallCheck(this, Kittydar);}