Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 我真的需要单身吗?_Javascript_Design Patterns_Singleton_Firefox Addon - Fatal编程技术网

Javascript 我真的需要单身吗?

Javascript 我真的需要单身吗?,javascript,design-patterns,singleton,firefox-addon,Javascript,Design Patterns,Singleton,Firefox Addon,我正在开发一个Firefox扩展,我想让多个窗口与相同的信息保持同步。工具栏根据窗口打开的时间定期向远程服务器查询信息。因为Firefox窗口都是独立的自包含环境,每个窗口都有自己的工具栏,运行独立的代码,所以我想在这里使用单例。实际上不需要多个请求,每个窗口可以有一个请求,但问题是没有全局主作用域凌驾于多个窗口上下文之上,只有窗口上下文。我想我应该创建一个工厂类来检查其中一个窗口是否已经运行了我的通知类的实例,如果已经运行了,则使用同一个实例来获取更新 这似乎是对独生子女的合理使用,但我一直在

我正在开发一个Firefox扩展,我想让多个窗口与相同的信息保持同步。工具栏根据窗口打开的时间定期向远程服务器查询信息。因为Firefox窗口都是独立的自包含环境,每个窗口都有自己的工具栏,运行独立的代码,所以我想在这里使用单例。实际上不需要多个请求,每个窗口可以有一个请求,但问题是没有全局主作用域凌驾于多个窗口上下文之上,只有窗口上下文。我想我应该创建一个工厂类来检查其中一个窗口是否已经运行了我的通知类的实例,如果已经运行了,则使用同一个实例来获取更新


这似乎是对独生子女的合理使用,但我一直在读关于他们是多么邪恶的野兽。这可以使用吗?

单例本身并没有什么固有的问题。问题在于它如何被(ab)使用:它本质上是一种拥有全局变量的奇特方式。单例只是让您拥有一个间接层次,它自身包含了大部分数据。但有时,这种模式是解决某些问题的唯一方法。那样的话,就很好了。然而,如果你能想出另一种方法,也许只需要多一点代码/内存/性能,如果可以的话,我会选择这种方法。否则,只要你清楚自己的处境,使用单例就没有什么错。

单例本身并不是邪恶的。是他们的虐待。。。(您通常可以使用DI容器将实例“单音化”,这使得这种模式不太受推荐)


我在你描述的领域没有任何经验。然而,在我看来,singleton似乎是一个合理的选择。

问题在于,就JavaScript而言,每个Firefox窗口都是一个完全独立的过程

所以是的,它会起作用,但前提是有条件地创建单例。如果它只是在全局范围内无条件创建的(在我的例子中,作为顶级扩展对象的成员),那么它将在所有窗口中

您将遇到的另一个问题是,windows需要一段时间来启动和运行JavaScript,而您没有任何类似同步的功能。完全可能的情况是,窗口1检查窗口2是否创建了单例,是否看到了单例,窗口2检查窗口1,是否看到了单例,然后两者都创建了自己的单例

我是根据经验说的:我编写了一个Firefox扩展,它做的事情与您想要做的事情非常相似:只有一个窗口应该检查远程服务器(当任何窗口关闭时,需要通知所有其他窗口)

(在mine中,启动时的每个窗口都会查询所有其他窗口以查找“主”窗口。)


解决这个问题的更简洁的方法是创建一个服务,就像浏览器向javascript公开的服务一样;但这需要用C语言编码,而不是javascript,这使得跨平台安装扩展更加困难。

单例到底是什么?整个扩展是一个全局范围。因此,要么他用一堆废话乱扔全局范围,要么他把所有东西都放在一个对象中,然后用一个对象乱扔全局范围(加上一个引导它的加载)。我做了后者。整个扩展是在全球范围内的。它只是窗口上的一个或多个变量。因此,要么他用一堆废话乱扔全局范围,要么他把所有东西都放在一个对象中,然后用一个对象乱扔全局范围(加上一个引导它的加载)。我做了后者。糟糕,我不能删除我的第一条评论。我会想也许我会偶尔检查一下,看看是否有多个实例,如果有,除了一个实例之外,是否删除所有实例?很遗憾,我甚至都不想麻烦,除非它是超大的。请记住,每个窗口的扩展副本所消耗的内存是代码的大小加上代码创建的任何对象。如果您最终编写了大量代码来删除一个小对象,那么您已经失败了。