为什么我的模块的执行顺序与预期不同?

时间:2016-02-21 12:04:39

标签: javascript ecmascript-6 babeljs

我正在使用Babel将一些ES6 JavaScript编译为ES5。我的代码遇到了一些问题,因为我的模块是以未定义的顺序进行评估的。

假设我有一个模块:

// a.js
class A {
  constructor() {
    this.prop = window.randomProperty;
    console.log("Prop " + this.prop);
  }
}

const a = new A();
export default a;

此模块依赖window.randomProperty进行设置,然后才能实例化。

现在我有一个主文件:

// main.js
import "babel-polyfill"; // Not sure if this is relevant

window.randomProperty = function() { return "hi"; };
console.log("randomProperty set");   

import A from "a";

控制台的输出是:

Prop undefined
randomProperty set

如何以正确的顺序执行代码?

3 个答案:

答案 0 :(得分:1)

在静态执行模块之前加载(并执行,除非是循环)导入。在您的情况下,a.js将在执行main.js之前加载。

如果您有依赖项,则应明确声明它们:

// random_prop.js
window.randomProperty = function() { return "hi"; };
console.log("randomProperty set");

// a.js
import "random_prop";
const a = {
    prop: window.randomProperty;
}
console.log("Prop " + a.prop);
export {a as default}

// main.js
import "babel-polyfill"; // Not sure if this is relevant
import a from "a";
console.log(a.prop);

当然,您也可以在a.js之前{main} {j}中的{_ 1}}中的random_prop.js,它可以在这个简单的设置中工作,但我不建议依赖这样的副作用。

答案 1 :(得分:0)

导出语句被挂起,因此在执行代码之前会加载导入。要按照您的需要执行它,您应该使用其他模块加载器,例如使用require

const A = require("a");

答案 2 :(得分:0)

您的问题在于您实例化A的位置,请尝试在main.js中执行此操作。看看这个:

// a.js
class A {
  constructor() {
    this.prop = window.randomProperty;
    console.log("Prop " + this.prop);
  }
}

// do not instantiate here
// const a = new A();
export default a;

请确保在此处创建对象:

// main.js
import A from "a";

window.randomProperty = function() { return "hi"; };
console.log("randomProperty set");

const a = new A();

原因是,当您导入模块时,它将调用任何与函数或类定义无关的方法。

希望这有帮助!