2014-09-03 50 views
1

我看到很多代碼herehereJS模塊模式:爲什麼賦值在擴展?

var module = (function (module) { 
    module.prototype.something_else = function() { 
    }; 
    return module; 
})(module); 

爲什麼var module =部分存在呢?爲什麼return module;如果以前的部分不需要?

我看到的用法:

var module = (function(module) {...})(module || {}); 

的情況下,當module是不是已經有時被定義...是,上述情況?

+0

如果你想擴展一個模塊? – Holybreath 2014-09-03 20:13:56

+0

是的,這件作品是爲了這些目的,但有些部分似乎對我來說是多餘的。 – gavenkoa 2014-09-03 20:15:51

+0

呃......需要'return module',否則你不會暴露這個模塊......還記得,那個javascript是函數作用域的。 – Holybreath 2014-09-03 20:18:20

回答

3

的代碼塊,如果模塊已被定義只用來和你想擴展它(例如,添加一個新方法):

var module = (function (module) { 
    module.prototype.something_else = function() { 
    }; 
    return module; 
})(module); 

它接受module作爲輸入參數,並返回延伸module。然後var module =的分配取代原來的module

回答您的問題一個接一個:

爲什麼VAR模塊=當前部分呢?

在上面的示例中(取自您的第一個URL),var module =是沒有必要的。他們提供的簡單例子很愚蠢。你可以完成與此完全一樣的事情:

module.prototype.something_else = function() {}; 

使用上面的圖案來擴展類,使在你的第二個網址提供的例子更有意義(http://www.adequatelygood.com/JavaScript-Module-Pattern-In-Depth.html):

var MODULE = (function (my) { 
    var old_moduleMethod = my.moduleMethod; 

    my.moduleMethod = function() { 
     // method override, has access to old through old_moduleMethod... 
    }; 

    return my; 
}(MODULE)); 

立即執行的函數創建一個新的範圍,我們可以保留舊方法var old_moduleMethod = my.moduleMethod;

下一個問題:

爲什麼返回模塊;如果以前的部分不需要?

你需要return module,否則該函數不會返回任何與var module =分配將被設置爲未定義的值。

下一個問題:

的情況下,當模塊是不是已經有時被定義...是,上述情況?

是的,就是這樣。如果module未定義,那麼您需要傳入一個空對象。但是,如果首先未定義對象,通常會使用模式來擴展對象。這是沒有意義的,只會使你的代碼複雜化。

+0

*「var module =」的賦值然後替換原來的模塊* - 我認爲'module'指向賦值之前和之後的內存中的相同地址。我對嗎?這就是爲什麼我感到沮喪...像'var a = a;' – gavenkoa 2014-09-03 20:42:38

+1

你是對的,它指向了內存中的同一個地方。對象在JavaScript中通過引用傳遞。這就是爲什麼第一個URL的可擴展性的例子很愚蠢。他們可能只是設置'module.prototype.something_else = function(){};'。我剛纔更新了我的答案。第二個URL中提供的示例提供了一個明確的用例,其中使用立即執行函數來擴展對象具有優勢。在那個例子中,我們能夠保留舊的方法。 – 2014-09-03 20:45:46

+1

我稍微更新了我的答案。在第一個URL中提供的示例中,您是正確的'var module ='不是必需的。 – 2014-09-03 20:51:09

1

要理解,它有助於重命名標識符來獲得相當於

var module = (function (module_impl) { 
    module_impl.prototype.something_else = function() { 
    }; 
    return module_impl; 
})(module || {}); 

module_impl是保持模塊的公共API的對象。所以填充後,匿名函數會將其返回給調用者,並將其分配給全局module。這樣,API現在可以使用module,而任何實現細節都隱藏在由匿名函數創建的閉包中。

module || {}現在是允許擴充:第一次被調用時,module仍然爲undefined,因爲對匿名函數的返回值的賦值尚未發生。因此`module || {}計算到第二個操作數。

爲了進一步說明爲什麼需要分配。第一次,存根被調用,它實際上是相同的

var module = (function() { 
    var module_impl = {}; 
    // ... 
    return module_impl; 
})()); 
+0

我的問題是爲什麼'var module ='部分。當你執行'module_impl.prototype.xxx ='時,即使沒有'var module ='賦值,它也可以通過'module'進行訪問...... – gavenkoa 2014-09-03 20:22:29

+0

否 - 模塊不會被定義,'module_impl'是匿名函數的本地並且第一次是新創建的對象'{}'。 – 2014-09-03 20:23:10

+0

所以沒有'module || {}'這個var module ='沒有意義?沒有'module ||的 – gavenkoa 2014-09-03 20:28:26