Consider the following files:
index.html:
<script type="module" src="main.js"></script>
main.js:
import Base from "./base.js";
import Derived from "./derived.js";
window.addEventListener("load", () => {
//Do stuff with Base and Derived
});
base.js:
import Derived from "./derived.js";
export default class Base {
foo(){
return new Derived();
}
}
derived.js:
import Base from "./base.js";
export default class Derived extends Base {}
If you try running this code, you will get an error saying "Uncaught ReferenceError: Cannot access 'Base' before initialization".
In this simple example, the solution is relatively easy: change the order of the two imports in main.js. But in a larger project it's much more difficult. In a very large project with about 100 files and multiple class hierarchies, I spent hours debugging problems like this, which was extremely frustrating.
Since functions can be accessed before initialization, the same thing should be possible with classes. The equivalent pre-ES6 code (but still with ES6 modules) works just fine without reordering any imports:
base.js:
import Derived from "./derived.js";
export default function Base(){}
Base.prototype.foo = function(){
return new Derived();
}
derived.js:
import Base from "./base.js";
export default function Derived(){}
Object.setPrototypeOf(Derived.prototype, Base.prototype);
It would be nice if ES6 classes could work the same way, that they can be accessed before initialization, at least for purposes of inheritance. In large projects this would save a lot of frustration and hours of debugging.