2012-05-09 24 views
4

我剛剛開始在一家新公司工作,並注意到在我的很多JS中看起來完全錯誤。我有點猶豫,沒有證實這是錯誤的,因爲我很小,我不是JS專家,這只是我的第二天,我不想看起來很愚蠢。模塊模式中的這個關鍵字?

所以,一般情況下我期待模塊模式看起來是這樣的:

MODULENAME = MODULENAME || {}; 

MODULENAME.SUBMODULENAME = (function() { 
    var bla = {}; 

    bla.somefunction = function() { 
     //do stuff 
    }; 

    //add more stuff to bla 
    return bla; 
}()); 

什麼,他們都在自己的代碼是:

MODULENAME = MODULENAME || {}; 

MODULENAME.SUBMODULENAME = (function() { 
    var that = this; 

    that.somefunction = function() { 
     //do stuff 
    }; 

    //add more stuff to that 
    return that; 
}()); 

現在當然由於功能ISN」 t被稱爲new關鍵字的構造函數或作爲方法,this綁定到window,他們將that定義爲this。所以他們基本上將全局對象中的所有東西都傾倒,並且其所有的子模塊名稱實際上都是別名window。有沒有人有理由這樣做?或者這對我來說真的是錯誤的嗎?

編輯:

我把var子模塊定義之前犯了一個錯誤,本來我寫的東西稍有不同,忘了刪除var。我試圖讓這個例子更清晰一些,希望我現在的意思更明顯。

編輯2:

而且我看螢火蟲執行腳本和他們肯定將一切window,該對象是一團糟。

+0

對不起,我不明白你的問題。你能解釋一下嗎? –

+0

你確定'this'沒有引用類或元素嗎?不知道我是否也理解你的問題。 –

+6

你剛從一家新公司開始,發現了一些你不確定的事情,而不是問你的同事誰知道代碼爲什麼它是這樣的你在SO上發佈的?似乎是開始新工作的糟糕方式。 –

回答

3

是的,看起來不對。

MODULENAME = MODULENAME || {}; // missing var 

var MODULENAME.SUBMODULENAME = (function() { // probably the missing var from above... 
    var that = this; 
    //add some stuff to that 
    return that; // that is the WINDOW- wrong. 
}()); 

DEMO的損害它可以做:

var x = function() { 
    alert('out'); 
} 
var MODULENAME = MODULENAME || {}; 

MODULENAME.SUBMODULENAME = (function() { 
    var that = this; 
    that.x = function() { 
     alert('DAMAGE'); 
    } 
}()); 

x();​ // alert DAMAGE and not "out" - messed up with the global object! 
+0

我不認爲這是錯的。我想這就是他想要的 –

+2

@MarkLinus。他們想污染全球對象?!我相信他們沒有。 **無論如何,如果你想做錯的事情,你做錯了,它仍然是錯誤的...... ** :) – gdoron

+0

聲明全局是一個很好的做法,但在這裏沒有什麼區別。 – RobG

0

模塊模式被不當使用,原因之一函數表達式不應該被用在它們的使用提供了沒有餘函數聲明。如果目的是創建全局函數(我懷疑它是),那麼應該使用:

function somefuncion() { 
    ... 
} 

如果他們的意圖是添加屬性(在這種情況下,方法)的對象,這是更可能的情況下,則:

MODULENAME.SUBMODULENAME.somemethod = function() { /* do stuff */ }; 

如果需要有條件地創建方法,例如基於特徵的檢測,那麼下面可能適合:

(function(global, undefined) { 

    // In here global is the global object 
    global.MODULENAME = global.MODULENAME || {}; 
    global.MODULENAME.SUBMODULENAME = global.MODULENAME.SUBMODULENAME || {}; 

    // and undefined is undefined, belt and braces approach 
    undefined = void 0; 

    // Direct assignment 
    function somemethod() { 
     //do stuff  
    }; 

    // Assign directly to the "namespace" object 
    MODULENAME.SUBMODULENAME.somemethod = somemethod; 

    // Conditional assignment 
    if (sometest) { 
    MODULENAME.SUBMODULENAME.anothermethod = function(){...}; 

    // Try another way... 
    } else if (someOtherTest) { 
    MODULENAME.SUBMODULENAME.anothermethod = function(){...}; 

    // Default 
    } else { 
    MODULENAME.SUBMODULENAME.anothermethod = function(){...}; 
    } 

    // Clean up 
    global = null; 

}(this)); 

一個與上面的問題是,外部函數內聲明的每個函數都有一個封閉回函數對象和它的環境,所以這是一個有點浪費資源。保持簡單效率更爲有效,只在真正需要的地方使用模塊模式,並在不使用普通函數聲明和賦值的情況下使用。不像時髦但更實用。