如何将静态方法分解为自己的文件并通过 ES6 正确导出?

How to break static methods out to their own file and export correctly via ES6?

这个问题是 的后续问题,它检查当实例和静态方法变大并使单个 class 文件太笨重而无法使用时如何拆分 class 文件.

该问题为实例方法找到了一个很好的答案,但仍然没有为静态工厂函数找到一个好的答案。考虑这个 ES6 class:

const fnCreate = require('./create');
const fnInstanceMethod = require('./instanceMethod');

class Door {
  constructor() {
    this.species = 'Oak';
    this.instanceMethod = fnInstanceMethod; // <-- works great
  }

  // Cannot connect static to required files...
  static create = fnCreate; // Syntax error unexpected '='

  // so static has to be written in class..
  static create() {
    return new Door(); // <-- the only line in fnCreate
  }
}
module.exports = Door; // but it exports and works fine...

你可以看到在静态函数中只需要 require 的地方会非常棒,但我还没有找到用 ES6 做到这一点的方法;它必须在 class 文件中实现。 所以,第 1 题,共 2 题,"Is there a way to require in a factory function and hook it up staticly in ES6 classes?"

这个 ES6 "inability" 让我做了一个 ES5 重写如下:

const fnCreate = require('./create');
const fnInstanceMethod = require('./instanceMethod');

function Door() {
  this.species = 'Oak';
  this.instanceMethod = fnInstanceMethod; // <-- works great
}

Door.create = fnCreate; // <-- totally solves the file problem; works fine

module.exports = Door; // <-- NOPE! Node says "Door" is not a constructor"

这样就避免了一个问题,步入了另一个问题。在 "regular" JS 下,该代码工作正常,在 Door.create() returns 下,一个新的 Door 对象。但是导出以某种方式破坏了实现,错误为 "Door is not a constructor." 问题 2 of 2,"Can the above ES5 code be exported to work correctly?"

使用 ES6 class,您可以分配给 class 对象并拥有本质上是静态方法的内容,就像您在 ES5 中所做的那样:

class Door {
  constructor() {
    this.species = 'Oak';
    this.instanceMethod = fnInstanceMethod; // <-- works great
  }
}
Door.create = fnCreate;

请注意,您的

this.instanceMethod = fnInstanceMethod; // <-- works great

虽然它 有效 ,但它可能不是最好的主意 - 如果你想从原型模仿标准继承(比如不需要将内容分离到多个文件中) ,你应该分配给原型对象,就像在 ES5 中一样:

class Door {
  constructor() {
    this.species = 'Oak';
  }
}
Door.create = fnCreate;
Door.prototype.instanceMethod = fnInstanceMethod;

我不确定您遇到的 "Door is not a constructor" 错误,但是对于您当前的实施,fnCreate(在单独的文件中)不会包含 Door,因此 fnCreate 将无法引用和创建 new Door。解决这个问题的一种方法是导出一个 Door 作为输入的函数,以及 returns 一个 returns 实例的函数:

// makeCreate.js
module.exports = theClass => () => new theClass();

// Door.js
const makeCreate = require('./makeCreate');
const fnInstanceMethod = require('./instanceMethod');
class Door {
  constructor() {
    this.species = 'Oak';
  }
}
Door.create = makeCreate(Door);
Door.prototype.instanceMethod = fnInstanceMethod;

module.exports = Door;

或者,ES5 中的makeCreate

function makeCreate(theClass) {
  return function() {
    return new theClass();
  }
}
module.exports = makeCreate;