2013-07-23 87 views
0

我看到下面的樣式從一個構造函數返回一個公共接口返回一個公共接口:從JavaScript構造

function AnObjectConstructor() { 

    function localFunc() {}; 
    function publicFunc() {}; 

    // public interface 
    var _this = { 
     publicFunc: publicFunc 
    }; 
    return _this; 
}; 

我喜歡這種風格,因爲公共接口顯然是在一個地方,也localFunc能訪問publicFunc而不使用_this

此代碼還可以被寫成這樣:

function AnObjectConstructor() { 

    function localFunc() {}; 
    function publicFunc() {}; 

    // public interface 
    var _this = this; 
    _this.publicFunc = publicFunc; 
    return _this; 
}; 

這兩種形式都意圖與使用新:

var obj = new AnObjectConstructor(); 
obj.publicFunc(); 

我不清楚這兩種形式是否相同,並希望有人能幫助我呢?

而且這種風格的任何一般性意見可以理解..

+0

下面是關於繼承的相關討論:http://alexsexton.com/blog/2010/03/superclassy-inheritance-with-javascript-video/和類http://alexsexton.com/inheritance/demo/ – Homer6

+0

通常,當您使用構造函數(使用new關鍵字)時,您將在原型上設置共享功能,以便它們不針對每個實例進行初始化。也許下面的答案會有幫助:http://stackoverflow.com/questions/16063394/prototypical-inheritance-writing-up/16063711#16063711 JavaScript不支持私有變量,並試圖使用閉包來創建它們是有代價的。這取決於你決定是否值得。 – HMR

回答

4

這兩個片段並沒有做同樣的事情。雖然這兩個片段都有公開引用publicFunc,但第一個片段返回對象字面量,第二個片段返回該函數的引用。這兩個例子都不是你如何創建函數構造函數的例子。您需要使用new關鍵字來實例化一個對象的實例:

function AnObjectConstructor() { 
    function localFunc() {}; 
    function publicFunc() {}; 
    // public interface 
    this.publicFunc = publicFunc; 
    //You don't need this line :return _this; 
}; 

var obj = new AnObjectConstructor(); 

我也刪除的_this創作,因爲沒有必要創建一個局部變量,併爲其分配this它。

編輯

第二種方法是首選在我看來,因爲它是利用JavaScript的內置構造對象的能力更常規的方法。第一種方法忽略了這一點,因爲它只是一個返回一個精簡對象字面值的函數。

+1

與此相關的一個問題是每個構造對象都有自己的'publicFunc'方法,而不是將它放在原型上,所以它只能創建一次。 – alex

+0

@alex這不是問題,但有一點不同:publicFunc是一個公共實例函數(每個對象一個函數),而在原型中定義的是公共共享函數(一個用於所有對象instanceof ctor)。 – metadings

+0

@metadings如果你創建了100個對象,並且運行時沒有對它進行任何優化,那麼你有100個直接在每個對象上的函數,而不是原型上的一次。這不是一個問題,還有一個糟糕的設計決定?國際海事組織,構建的對象應儘可能輕量級,常見的方法應該只存在原型。 – alex

0

當與new運營商使用,他們確實將是相同的(至少就他們如何目前定義),作爲規範說當執行構造函數時將this設置爲新構造的對象,或者如果返回對象(您的第一個示例),則將其用作構造對象。返回自己的對象時的差異是它不會將[[prototype]]設置爲AnObjectConstructor.prototype

此外,如果你打電話給他們沒有new運營商,那麼他們的行爲將會非常不同。第一個將會返回一個新的對象,就像工廠風格的方法一樣,但第二個對象將增加全局對象,這幾乎不是你想要的。

+0

我很抱歉,我認爲函數的名稱會使它清楚,我的意圖是這個對象僅用於new,如下所示:var obj = new AnObjectConstructor();鑑於此,這兩種形式有什麼不同?他們中的任何一個更好?爲什麼你說他們不是構造函數的好例子? – kofifus

+0

第一個是不常見的,使用'new'並不會給你任何新的功能,而只是調用它,所以我不會使用它。你應該使用你的第二種形式,但是把所有常用的方法放在原型上,而不是直接放在構造的對象上。 – alex

1

有區別。你的第一個構造函數可以用兩種方式來調用:

var myObject = AnObjectConstructor(); 

var myObject = new AnObjectConstructor(); 

這是因爲第一個構造函數創建手動返回的對象。對於new運算符,當您返回自己的手工對象時,由引擎自動創建的this對象會被有效地丟棄。

但是,您的第二個構造函數依賴於您使用new運算符調用它。如果您不使用new,則會污染當前的this,這可能是另一個對象或全局空間。

+0

對不起,我認爲函數的名稱會說清楚,我的意圖是隻爲這個對象使用新的,如: var obj = new AnObjectConstructor(); 鑑於這兩種形式之間是否有區別?他們中的任何一個更好?爲什麼你說他們不是構造函數的好例子? – kofifus