Javascript 为什么模块模式会创建一个单例?

Javascript 为什么模块模式会创建一个单例?,javascript,module,Javascript,Module,当我尝试创建此模块的不同实例时,它不起作用 这似乎是一个单身汉。我一次只能有一个实例 什么机制限制构造函数publik()仅在实例上具有 尝试重写模块类,以便可以使用它创建不同的实例。您可能希望将“test”属性更改为静态属性,因为我已经为您更改了它 var Module = function(){} Module.prototype.test; Module.prototype.get = function() { document.getElemen

当我尝试创建此模块的不同实例时,它不起作用

这似乎是一个单身汉。我一次只能有一个实例

什么机制限制构造函数publik()仅在实例上具有


尝试重写模块类,以便可以使用它创建不同的实例。您可能希望将“test”属性更改为静态属性,因为我已经为您更改了它

var Module = function(){}

    Module.prototype.test;
    Module.prototype.get = function()
    {
       document.getElementById( 'a'+this.test ).innerHTML = this.test;
    };
    Module.prototype.set = function( value )
    {
       this.test = value;
    }

简单的回答是:结束

长答案(如果我的回答正确,请评论以便我更正):

  • 当脚本加载时,将立即执行模块变量。(由函数周围的括号表示。)()

  • 在该模块中,您的publik变量被声明,即使在函数完成时,它仍保留在闭包中

  • 通过后续调用,您仍然可以访问自动执行的模块。它总是得到相同的闭包空间、函数范围和相同的对象,简言之,所以publik变量实际上总是相同的


  • 模块模式并不打算以您描述的方式使用。它用于创建一个模块并对外部代码隐藏状态,即公开一个外部代码可以与之通信的公共接口,但将其余部分隐藏

    这可以防止其他代码依赖于您在内部使用的变量或函数,因为当您重命名任何内容时,它们会被破坏

    此外,模块应该是单态的;拥有多个相同的模块就像在代码中有两个相同的类。。。没有道理

    这就是模块模式的外观

    var Module = (function($) {
        // the $ symbol is an imported alias
    
        // private variable
        var id = 0;
    
        // private function
        function increaseId()
        {
            return ++id;
        }
    
        // return public interface
        return {
            nextId: function() {
                // we have access to the private function here
                // as well as the private variable (btw)
                return increaseId();
            }
        }
    }(jQuery)); // we import jQuery as a global symbol
    
    Module.nextId(); // 1
    Module.nextId(); // 2
    Module.id; // undefined
    Module.increaseId(); // error
    

    您可以看到只有
    .nextId()
    是如何公开的,但没有其他私有变量/函数。

    您编写的代码不会创建单例。由于
    test
    变量是一个全局变量,因此它的作用仅类似于一个单例


    要修复此更改,请将
    test
    更改为
    this.test
    ,以便将变量附加到每个实例。

    我以前使用过此变量,但不喜欢b.c.样式。没有包含括号。因此每次调用new时,它实际上不是一个新函数对象,而是同一个?是的。更准确地说,当您在(function(){}())模式中封装一个函数时,它会在加载时自动执行,并将结果放在它的位置。因此,您的脚本最终看起来像(内部)var Module=YourObjectWithGetAndSetMethods;当你做一个var x=Module()时;您正在调用一个已经实例化的对象,因此使用了实例化的publik变量。对我来说,这似乎是一个伪造的模式。它“打破”了关键字“新”的含义。你同意吗?如果是这样的话,为什么人们要用这个?很明显,这并不是我发明的。关于伪模式,你们不应该在单例中使用“new”。单例在创建应用程序时很有用,您可以使用自己的名称空间。以YUI或jQuery为例。如果“$”(或“YUI”)对象不是单例对象,那么任何jQuery模块文件都将初始化它自己的“$”。你必须使用firstYUI.onePlugin和secondYUI.otherPlugin。。。按照单例的方式,您只有一个YUI对象,所有“插件”或小部件或任何绑定在其中的东西。只是在这里遇到了这样的情况:“通过新关键字创建的每个实例都连接到原始原型”:
    var Module = (function($) {
        // the $ symbol is an imported alias
    
        // private variable
        var id = 0;
    
        // private function
        function increaseId()
        {
            return ++id;
        }
    
        // return public interface
        return {
            nextId: function() {
                // we have access to the private function here
                // as well as the private variable (btw)
                return increaseId();
            }
        }
    }(jQuery)); // we import jQuery as a global symbol
    
    Module.nextId(); // 1
    Module.nextId(); // 2
    Module.id; // undefined
    Module.increaseId(); // error