ES6模块和继承

时间:2016-03-09 22:21:07

标签: javascript inheritance ecmascript-6

我有以下JavaScript文件:

的src / JS /类/ Lexus.js:

import {Car} from 'src/js/classes/Car';

export class Lexus extends Car {
  constructor() {
    super("Lexus");
  }
}

的src / JS /类/ Mercedes.js:

import {Car} from 'src/js/classes/Car';

export class Mercedes extends Car {
  constructor() {
    super("Mercedes");
  }
}

的src / JS /类/ 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();
    }
  }
}

和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);

有趣的是,如果我将 LexusMercedes导入Car类并在app.js中调用工厂方法 - 一切正常;但是,如果我将 {/ 1>}和Lexus 导入Car类,我会收到错误:

  

超级表达式必须为null或函数,而不是未定义

我想念什么?

1 个答案:

答案 0 :(得分:5)

通常,您希望具有这样的循环依赖关系。 在最好的时候循环依赖,打破一切,不编译(或转换)。 在最糟糕的时候,循环依赖会导致合并和版本冲突,导致代码很难辨别,看起来它们正常工作,直到它们停止,由于一些可怕的状态假设引起的一些可怕的错误。

你的解决方案(如果你在这种继承形式上死定)将是将Car提取到它自己的文件/类中,它可以单独导入,并使工厂与上课。

其中,英语完全有道理 汽车不构建雷克萨斯(Lexi?)。

此外,如果你 想要保留这个(不是一个好主意),那么你应该有一个注册方法,而不是硬编码的解决方案,你注册“雷克萨斯”和功能这是一个新的雷克萨斯。

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;

情况变得更糟,但这已经很糟糕了。

如果你走另一条路:

// 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");
}

现在,没有班级需要了解他们不应该做的事情。