我最近了解到,所有 Node 模块都会被缓存,并且在大多数情况下的行为类似于单例。
我试图解决的问题是不要返回同一实例中的每个导入结果。这可能很容易弄清楚,但由于我是 Node 和 ES6 的新手,所以我很难找到可靠的设计模式。
我想要实现的目标是:
- 私有(private)字段
- 导入模块的使用者可以新建实例
- 比较实例
我能想到的最好的办法如下:
export default () => {
let _foo = 'bar';
return new class {
get foo() {
return _foo;
}
set foo(value) {
_foo = value;
}
};
};
然而,这并不能完全满足我想要实现的所有目标。
使用此方法导入模块不能使用instanceof来比较原型(prototype)。
导入器在创建实例时是否使用 new 关键字也没关系。调用 let instance = new Module()
和 let instance = Module()
会产生相同的结果。
我尝试通过从函数返回中删除 new 关键字来解决此问题,但这导致导入程序必须执行以下操作才能获取新实例:new (Module())
我也尝试过导出构造函数,但这导致私有(private)字段丢失。
从 Node 模块导出构造函数/类的正确方法是什么?
更新:
经过更多尝试后,我得出以下结论:
const _sFoo = Symbol();
export default class {
constructor() {
this[_sFoo] = 'default';
}
get foo() {
return this[_sFoo];
}
set foo(value) {
this[_sFoo] = value;
}
}
这似乎满足了我所有的目标,但我仍然不确定这是否是最好的设计模式......
最佳答案
The problem I am trying to solve is to not have every import result in the same instance being returned. This is probably very simple to figure out however I'm having trouble landing on a solid design pattern as I'm new to Node and ES6.
您有几个选择:
您可以导出构造函数,并让加载模块的代码调用该构造函数来创建自己的对象。这允许调用代码根据需要创建任意数量的独立对象。导出构造函数需要调用者使用
new
,除非构造函数显式检测到它们是在没有new
的情况下调用的,然后进行调整以仍然返回新实例。您可以导出工厂函数,并让加载模块的代码调用该工厂函数来创建任意数量的自己的对象。工厂函数将像普通函数一样被调用,并且每次调用时都会返回一个新对象。
您可以导出一个方法,该方法在调用时可以执行您想要的任何操作,包括创建所需的对象并返回它(也许也嵌入到其他事物的对象中)。这只是工厂函数的一个变体,但可能同时包含很多东西。
The goals I'm trying to achieve are:
Private fields
上面的内容对每个对象的私有(private)字段没有任何帮助。这是一个完全独立的讨论。
Consumers of the imported module can new up instances
上面的选项1允许调用者直接使用new
。其他选项是工厂函数,因此它们不会使用 new
。
instanceof comparison
您必须直接导出构造函数(上面的选项 1)才能使用 instanceof
。其他选项不会导出构造函数,因此您没有任何可以使用 instanceof
的内容。
What is the proper way to export a constructor function/class from a node module?
您只需导出构造函数。在 Javascript 中,构造函数只是函数,因此您只需导出构造函数,然后调用者就可以使用 let x = new SomeConstructor()
创建自己的对象。他们同样可以使用 if (x instanceof SomeConstructor) 。使用 ES6 语法,您只需导出类名,这相当于导出构造函数。
关于javascript - 在 NodeJS 中导出非单例类的正确方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42601598/