Javascript 需要节点中的单例实例

Javascript 需要节点中的单例实例,javascript,node.js,require,Javascript,Node.js,Require,我在一些代码中发现了以下内容: var Log = require('log'); // This creates a singleton instance module.exports = new Log('info'); 我的第一个反应是“不可能是单例的”,但我记得有一篇文章概述了Node.js是如何执行require()语句的,其中提到缓存require语句并在后续调用中使用它们 所以基本上我的问题是,导出一个新对象()实际上是在幕后创建一个单例吗 我知道在JavaScript中还有其

我在一些代码中发现了以下内容:

var Log = require('log');

// This creates a singleton instance
module.exports = new Log('info');
我的第一个反应是“不可能是单例的”,但我记得有一篇文章概述了Node.js是如何执行
require()
语句的,其中提到缓存require语句并在后续调用中使用它们

所以基本上我的问题是,导出一个
新对象()
实际上是在幕后创建一个单例吗


我知道在JavaScript中还有其他创建单例的方法,但这似乎是在节点内部实现的一种非常方便的方法(如果它确实有效的话)。

它不是真正的单例,因为您可以创建任意多的
Log
实例。但是你可以这样使用它。否则,您只需通过
var mySingleton={}
创建一个普通对象,并将属性和方法附加到它

然后您可以将
mySingleton
分配给
模块。在其他模块中导出
require()

foo.js:

var mySingleton = {
    someMethod = function () {}
};

module.exports = mySingleton;
bar.js:

var singletonClass = require('./foo.js');

singletonClass.someMethod();

由于您可以创建任意多的
Log
实例,因此它不是一个真正的单例。但是你可以这样使用它。否则,您只需通过
var mySingleton={}
创建一个普通对象,并将属性和方法附加到它

然后您可以将
mySingleton
分配给
模块。在其他模块中导出
require()

foo.js:

var mySingleton = {
    someMethod = function () {}
};

module.exports = mySingleton;
bar.js:

var singletonClass = require('./foo.js');

singletonClass.someMethod();

为什么不自己测试一下呢

$ cat test.js
module.exports = Math.random();
$ node
> var a = require("./test");
undefined
> var a = require("./test");
undefined
> a === b
true
是的,node.js似乎确实缓存了导出的值。因此,如果您再次需要相同的模块,它将返回缓存的值,而不是创建新的值


但是应该注意的是,程序员可以只
要求(“log”)
并手动创建一个新实例。所以从这个意义上讲,它不是一个单身汉。

为什么不自己测试一下呢

$ cat test.js
module.exports = Math.random();
$ node
> var a = require("./test");
undefined
> var a = require("./test");
undefined
> a === b
true
是的,node.js似乎确实缓存了导出的值。因此,如果您再次需要相同的模块,它将返回缓存的值,而不是创建新的值


但是应该注意的是,程序员可以只
要求(“log”)
并手动创建一个新实例。所以从这个意义上讲,它不是一个单例。

是的,这是Node.js中最接近单例的东西
require()
在第一次调用时缓存每个模块,因此每个后续的
require()
总是返回相同的实例

但是,您必须知道,这并不总是强制执行的。缓存可以修改/删除,模块也可以使用其完整路径进行缓存,简言之,这意味着如果您在包中定义一个单例,并且您的包作为嵌套依赖项安装,那么在同一应用程序的上下文中可能有多个“单例”实例。 快速示例:

Application
  node_modules
    PackageA
      node_modules
        YourPackageWithSingleton
    PackageB
      node_modules
        YourPackageWithSingleton

通常您不必担心这一点,但如果您确实需要在整个应用程序中共享一个对象,唯一的解决方案是使用全局(不鼓励)或依赖项注入。

是的,这是Node.js中最接近单例的方法
require()
在第一次调用时缓存每个模块,因此每个后续的
require()
总是返回相同的实例

但是,您必须知道,这并不总是强制执行的。缓存可以修改/删除,模块也可以使用其完整路径进行缓存,简言之,这意味着如果您在包中定义一个单例,并且您的包作为嵌套依赖项安装,那么在同一应用程序的上下文中可能有多个“单例”实例。 快速示例:

Application
  node_modules
    PackageA
      node_modules
        YourPackageWithSingleton
    PackageB
      node_modules
        YourPackageWithSingleton

通常您不必担心这一点,但如果您确实需要在整个应用程序中共享一个对象,唯一的解决方案是使用全局(不鼓励)或依赖项注入。

有点一次性,在什么情况下缓存会使自身失效?谢谢你提供的关于子模块的信息,我没有想到。有点像一次性的,在什么情况下缓存会自动失效?谢谢你提供关于子模块的信息,我没想到。