我最近了解到,在大多数情况下,所有节点模块都被缓存并且与单例类似。
我想解决的问题是没有返回同一个实例中的每个导入结果。这可能很容易弄清楚,但是我很难登陆坚固的设计模式,因为我是Node和ES6的新手。
我努力实现的目标是:
我能想出的最好成绩如下:
export default () => {
let _foo = 'bar';
return new class {
get foo() {
return _foo;
}
set foo(value) {
_foo = value;
}
};
};
然而,这并不能完全达到我想要实现的所有目标。
使用此方法导入模块无法使用instanceof来比较原型。
如果导入者在创建实例时使用new关键字也无关紧要。调用let instance = new Module()
和let instance = Module()
会导致同样的事情。
我试图通过从函数返回中删除new关键字来解决这个问题,但是这导致导入程序必须执行以下操作来获取新实例:new (Module())
我也尝试过导出构造函数,但这导致了私有字段的丢失。
从节点模块导出构造函数/类的正确方法是什么?
更新:
在玩了一些之后,我能够想出以下内容:
const _sFoo = Symbol();
export default class {
constructor() {
this[_sFoo] = 'default';
}
get foo() {
return this[_sFoo];
}
set foo(value) {
this[_sFoo] = value;
}
}
这似乎符合我的所有目标,但我仍然不确定这是否是最好的设计模式...
答案 0 :(得分:3)
我想解决的问题是没有返回同一个实例中的每个导入结果。这可能很容易弄清楚,但是由于我是Node和ES6的新手,因此无法登陆稳固的设计模式。
您有几个选择:
您可以导出构造函数,让正在加载模块的代码调用该构造函数来创建自己的对象。这允许调用代码根据需要创建任意数量的独立对象。导出构造函数需要调用者使用new
,除非构造函数明确检测到它们在没有new
的情况下被调用,然后再适应仍然返回一个新实例。
您可以导出工厂函数,让正在加载模块的代码调用该工厂函数,以根据需要创建任意数量的对象。工厂函数将被称为普通函数,并且每次调用它时都会返回一个新对象。
您可以导出一个方法,该方法在调用时可以执行任何操作,包括创建所需对象并返回它(也可能嵌入其他对象中)。这只是工厂功能的一种变体,但可能同时包含很多东西。
我想要实现的目标是:
私人字段
以上对每个对象的私有字段都没有帮助。这是一个完全独立的讨论。
导入模块的消费者可以新建实例
上面的选项1允许呼叫者直接使用new
。其他选项是工厂功能,因此他们不会使用new
。
比较实例
您必须直接导出构造函数(上面的选项1)才能使用instanceof
。其他选项不会导出构造函数,因此您没有任何内容可以使用instanceof
。
从节点模块导出构造函数/类的正确方法是什么?
您只需导出构造函数。在Javascript中,构造函数只是函数,因此您只需导出构造函数,然后调用者就可以使用let x = new SomeConstructor()
创建自己的对象。他们同样可以使用if (x instanceof SomeConstructor)
。使用ES6语法,您只需导出类名称,这相当于导出构造函数。