Javascript 什么时候保证单身人士会这样?

Javascript 什么时候保证单身人士会这样?,javascript,node.js,npm,Javascript,Node.js,Npm,假设您有一个定义 var theThing = {} exports.theThing = theThing 包装消费者执行以下操作: var thing1 = require('thing') var thing2 = require('thing') assert(thing1.theThing === thing2.theThing) 这似乎通过了快速测试。大概当节点执行第二个require时,它会注意到东西已经实例化,并悄悄地返回一个指向现有实例的指针 现在假设发生以下情况: np

假设您有一个定义

var theThing = {}
exports.theThing = theThing
包装
消费者
执行以下操作:

var thing1 = require('thing')
var thing2 = require('thing')
assert(thing1.theThing === thing2.theThing)
这似乎通过了快速测试。大概当节点执行第二个
require
时,它会注意到
东西已经实例化,并悄悄地返回一个指向现有实例的指针

现在假设发生以下情况:

  • npm上发布了两个版本的
    thing
    ,分别为1.0.0和2.0.0

  • npm上发布了两个软件包,
    consumer1
    consumer2
    ;它们分别依赖于
    thing
    的1.0.0和2.0.0版本,并且每个版本都重新导出
    thing

  • 另一个包装商
    endConsumer
    依赖于
    consumer1
    consumer2

因此,如果
endConsumer
尝试此测试:

assert(consumer1.theThing === consumer2.theThing)
那一定会失败,对吗?此时,节点不能重用
thing
的一个实例,因为需要包的两个不同版本


我想你最终应该能够依赖一个进程中任何地方都是唯一的单例,只要导出该单例的包上的所有可传递依赖项都在该包的同一版本上。但是这个猜测是正确的,还是实际的规则是其他的呢?

是的,这将失败,并有助于证明为什么单例是一个糟糕的想法。这确实是一个很好的例子,说明了单例的问题,而npm解决版本冲突的草率方式加剧了这一问题。也就是说,正如@Ryan指出的,单身是不好的。我认为单身对于应用程序的特殊情况最有意义。当开发一个将被用作其他包依赖项的包时,由于op所述的原因(以及其他几个原因),这是一个糟糕的设计,但是对于一个永远不会被依赖的独立项目来说,单例确实不是一个糟糕的决定,并且有助于揭示所述设计模式的好处。@zillaofthegods,但我真的更喜欢尽可能减少状态。有时,一个有状态的单例是必要的,但在这种情况下,它不应该留给npm,NodeJ需要函数通过模块加载缓存来管理它。我绝对同意不让npm来管理它(正如您所提到的糟糕的依赖关系管理)。奇怪的是,我想知道你反对有状态的“性”?我不一定不同意,只是好奇而已。