2012-05-13 31 views
1

可能重複:
Javascript: Module Pattern vs Constructor/Prototype pattern?類仿真 - 模塊模式與函數對象

我想用類模擬在JavaScript中。這是一個偏好。

我一直在使用模塊模式,但正在考慮使用一個簡單的函數對象,因爲我可以創建公共和私有成員變量和函數。

Here是功能對象仿真一個類的一個示例:

var input = document.getElementById('input'); 
var output = document.getElementById('output'); 

function test() 
{ 
    var private_var = 'private_var'; 
    var private_func = function(){ return 'private_func';}; 
    var my = {}; 
    my.public_var = 'public_var'; 
    my.public_func = function(){ return 'public_func';}; 
    return my; 
} 

var object_test = new test(); 

alert('| ' + object_test.public_var); 
alert('| ' + object_test.private_var); 

alert('| ' + object_test.public_func()); 
alert('| ' + object_test.private_func()); 

​ 

Here是一個模塊模式模擬的類的實例。

主要區別是什麼?除了使隱含的全球明確的能力之外,還有什麼?

+0

模塊是單例,其他不是。 –

+0

http://stackoverflow.com/questions/3790909/javascript-module-pattern-vs-constructor-prototype-pattern – c69

+0

@馬特..我的對象都是單身,所以這是很好的知道...一般 –

回答

0

我相信主要的問題是你的test()函數仍然可以在沒有new關鍵字的情況下被調用,並且在這種情況下'this'的值將指向被調用者上下文(最有可能是全局的),而不是到test()內部的閉包,導致不希望的效果,如污染全局名稱空間和不同實例覆蓋對方的值。如果您將構造函數作爲常規函數調用,解釋器不會警告您。如果您的代碼不打算與一羣好的用戶共享,並且您正在使用某些構造函數的命名約定,例如構造函數的Test()和常規函數的test(),那麼您仍然是安全的。 它也有助於在代碼中保留一些規則,例如強制你在return語句中定義任何'public'成員,其中所有成員都將相鄰,並作爲一個乾淨的外觀。這在大型代碼庫中很有趣。

+0

非常好的一點,我沒有考慮過使用新的。 –

1

我可能誤解了你的意思是「功能對象」,但據我瞭解,這些模式並不是真正可以互換的。

「模塊模式」用於根據需要定義具有方法和屬性的單個對象。這方面的一個很好的例子是Math和自定義模塊的一個簡單的例子只是一個Object實例:

var Module = { prop: 'prop' }; 
alert(Module.prop); 

但是,以這種方式,模塊是不是類。您無需致電new Math即可使用它們。您只需調用他們的方法(Math.abs())或獲取/設置其屬性(Math.PI)。

函數對象」 - 或者我所說的構造函數 - 是JavaScript最接近「類」定義的概念。 ObjectStringArray。這些和其他是爲創建新實例而定義的構造函數。

你給我的片段當然可以修改爲一個構造函數:

// common-practice: constructors are named in PascalCase 
function Test() 
{ 
    var private_var = 'private_var'; 
    var private_func = function(){ return 'private_func';}; 

    this.public_var = 'public_var'; 
    this.public_func = function(){ return 'public_func';}; 
} 

var object_test = new Test(); 

而且,這些模式並不一定,甚至相互排斥的。處理像模塊這樣的構造函數將允許定義「靜態」成員:

var Foo = (function() { 
    function constructor() { 
     var private_var = 'private_var'; 
     this.public_prop = 'public_prop'; 
    } 

    var private_shared = 'private_shared'; 
    constructor.public_shared = 'public_shared'; 

    return constructor; 
})(); 

alert(Foo.public_shared);  // 'public_shared' (module property) 
alert(new Foo().public_prop); // 'public_prop' (instance property)