admin 管理员组文章数量: 1086019
I have the following JavaScript files:
src/js/classes/Lexus.js:
import {Car} from 'src/js/classes/Car';
export class Lexus extends Car {
constructor() {
super("Lexus");
}
}
src/js/classes/Mercedes.js:
import {Car} from 'src/js/classes/Car';
export class Mercedes extends Car {
constructor() {
super("Mercedes");
}
}
src/js/classes/Car.js:
import {Lexus} from 'src/js/classes/Lexus'; //either of those imports works, but not both!
import {Mercedes} from 'src/js/classes/Mercedes'; //either of those imports works, but not both!
export class Car {
constructor(make) {
this.make = make;
}
static factory(msg) {
switch(msg) {
case "Lexus":
return new Lexus();
case "Mercedes":
return new Mercedes();
}
}
}
and app.js:
import {Lexus} from 'src/js/classes/Lexus';
import {Mercedes} from 'src/js/classes/Mercedes';
import {Car} from 'src/js/classes/Car';
var car = Car.factory("Lexus");
console.log(car);
The interesting thing, if I import either Lexus
or Mercedes
to the Car class and call the factory method in app.js - everything works fine; however if I import both Lexus
and Mercedes
to the Car class I got an error:
Super expression must either be null or a function, not undefined
What do I miss ?
I have the following JavaScript files:
src/js/classes/Lexus.js:
import {Car} from 'src/js/classes/Car';
export class Lexus extends Car {
constructor() {
super("Lexus");
}
}
src/js/classes/Mercedes.js:
import {Car} from 'src/js/classes/Car';
export class Mercedes extends Car {
constructor() {
super("Mercedes");
}
}
src/js/classes/Car.js:
import {Lexus} from 'src/js/classes/Lexus'; //either of those imports works, but not both!
import {Mercedes} from 'src/js/classes/Mercedes'; //either of those imports works, but not both!
export class Car {
constructor(make) {
this.make = make;
}
static factory(msg) {
switch(msg) {
case "Lexus":
return new Lexus();
case "Mercedes":
return new Mercedes();
}
}
}
and app.js:
import {Lexus} from 'src/js/classes/Lexus';
import {Mercedes} from 'src/js/classes/Mercedes';
import {Car} from 'src/js/classes/Car';
var car = Car.factory("Lexus");
console.log(car);
The interesting thing, if I import either Lexus
or Mercedes
to the Car class and call the factory method in app.js - everything works fine; however if I import both Lexus
and Mercedes
to the Car class I got an error:
Super expression must either be null or a function, not undefined
What do I miss ?
Share Improve this question edited Mar 9, 2016 at 22:33 Adi Prasetyo 1,0421 gold badge16 silver badges43 bronze badges asked Mar 9, 2016 at 22:21 koryakinpkoryakinp 4,1357 gold badges27 silver badges59 bronze badges 8- I'm not sure if you need to import Lexus and Mercedes in the app.js, since they're not constructed there. – Sterling Archer Commented Mar 9, 2016 at 22:28
- 2 Are you sure the error isn't based off of Car and your specific make classes being circular dependent on each other? – Binvention Commented Mar 9, 2016 at 22:29
- 2 what happens if you put a break within the cases after each new statement? Edit: nvm youre returning so the switch is out of scope sry – xetra11 Commented Mar 9, 2016 at 22:29
- Sterling Archer, I do need to import Lexus and/or Mercedes to app.js, in order to instantiate from factory method. – koryakinp Commented Mar 9, 2016 at 22:33
- @Binvention, if error based on Car and make classes being circular dependent on each other, how it explain the fact that either imports works, but not both ? – koryakinp Commented Mar 9, 2016 at 22:47
1 Answer
Reset to default 8Typically, you want to not have circular dependencies like this. Circular dependencies at the best of times, break everything and don't pile (or transpile). Circular dependencies at the worst of times, cause merge and versioning conflicts, cause code that's really hard to discern, look like they're working just fine, until they stop, with some terrible bug caused by some terrible state assumptions.
Your solution (if you are dead-set on this form of inheritance) is going to be to extract Car
into its own file/class, which can be imported separately, and to have the Factory be separate from the class.
Which, in English makes plete sense.
Cars don't construct Lexuses (Lexi?).
Additionally, if you did want to keep this (not a great idea), then you should have a register method, not a hard-coded solution, whereby you register "Lexus" and the function which makes a new Lexus.
import Car from "./car";
class Lexus extends Car {
constructor () {
super("Lexus");
}
// starting to look like a bad idea
static make () {
return Car.make("Lexus");
}
// starting to look worse
static register () {
/* this register method does nothing, so that Lexus can't make other cars... */
}
}
Car.register("Lexus", () => new Lexus());
export default Lexus;
It gets worse, but this is already plenty bad.
If you go the other route:
// carfactory.js
const carTypes = new Map();
class CarFactory {
static register (name, implementation) {
carTypes.set(name, implementation);
return CarFactory;
}
static make (name) {
const makeCar = carTypes.get(name);
return makeCar();
}
register (name, implementation) {
CarFactory.register(name, implementation);
return this;
}
make (name) { return CarFactory.make(name); }
}
export default CarFactory;
// index.js
import Car from "./classes/car";
import Lexus from "./classes/lexus";
import CarFactory from "./factories/car";
CarFactory
.register("Lexus", () => new Lexus())
.register("Bentley", () => new Bentley());
init( CarFactory );
function init (Car) {
const lexus = Car.make("Lexus");
}
Now, no classes need to know about things they shouldn't have to.
本文标签: javascriptES6 modules and inheritanceStack Overflow
版权声明:本文标题:javascript - ES6 modules and inheritance - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://roclinux.cn/p/1744031866a2521651.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论