如何将静态方法分解为自己的文件并通过 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;
这个问题是
该问题为实例方法找到了一个很好的答案,但仍然没有为静态工厂函数找到一个好的答案。考虑这个 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;