2012-05-21 34 views
9

當我嘗試創建此模塊的不同實例時,它不起作用。爲什麼模塊模式創建單例?

它似乎是一個單身人士。我一次只能有一個實例。

什麼機制限制構造函數publik()只對實例有效?

http://jsfiddle.net/AVxZR/

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

var object1 = new Module(); 
var object2 = new Module(); 

object1.set('1'); 
object2.set('2'); 


object1.get(); 
object2.get(); 

回答

5

簡短的回答:關閉。

長的答案(如果我是正確的,請發表評論,所以我可以糾正):

  1. 你的模塊var是一個執行腳本加載時立即。 (用函數的括號表示)。()

  2. 在該模塊中,即使函數完成,您的publik var也會被聲明,並且它的仍留在關閉中!

  3. 對於後續調用,您仍然可以訪問自動執行的那個模塊。簡而言之,它始終獲得相同的閉包空間和函數作用域以及相同的對象 - 因此,您的publik變量實際上始終是同一個對象。

+0

因此,每次我調用新的時候,它都不是一個新的函數對象,它是一樣的嗎? –

+1

是的。爲了更加準確,當你在(function(){}())模式中包含一個函數時,它會在加載時自動執行,並且結果放在它的位置。所以你的腳本最終看起來像(內部)var Module = YourObjectWithGetAndSetMethods; 而當你做一個var x = Module();您正在調用已實例化的對象,因此調用了實例化的publik變量。 – Zlatko

+0

似乎像一個假的模式給我。它「打破」關鍵詞「新」的含義。你同意嗎?如果是這樣,人們爲什麼使用這個?我顯然沒有發明它。 –

4

嘗試重寫模塊類,這樣就可以使用它來創建不同的實例。您可能希望將「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; 
    } 
+0

我以前用過這個,但不喜歡b.c.的風格。沒有包含括號。 –

10

模塊模式並不打算以您所描述的方式使用。它用於創建一個模塊並隱藏外部代碼的狀態,即您公開一個外部代碼可以與之通信的公共接口,但您將其餘部分隱藏起來。

這可以防止其他代碼依賴於內部使用的變量或函數,因爲當您重命名任何內容時它們會中斷。

此外,模塊應該是單身;有多個相同的模塊就像在你的代碼中有兩個相同的類......沒有意義。

這是一個模塊模式應該如何。

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()是如何只露,但沒有其他私有變量/功能。

1

您的代碼不會創建單身人士。它只能像單身人士一樣行事,因爲你的test變量是一個全局變量。

要將此更改test修復爲this.test,以便將變量附加到每個實例。