2010-08-05 124 views
15

我想爲我的應用程序創建一個全局名稱空間,並且在該名稱空間中我想要其他名稱空間:JavaScript名稱空間

E.g.

Dashboard.Ajax.Post() 

Dashboard.RetrieveContent.RefreshSalespersonPerformanceContent(); 

我也想將它們放置在單獨的文件:

  • Ajax.js
  • RetrieveContent.js

但是我一直在使用this方法試過了,但它贏得了」 t工作,因爲在2個獨立的地方使用相同的變量名稱作爲命名空間。任何人都可以提供替代品嗎

謝謝。

+0

名稱命名空間一些不同的東西? – 2010-08-05 00:50:42

+0

我想這是一種選擇,但是我希望將所有東西都包含在一個命名空間下,因爲我認爲它會更有序。 – 2010-08-05 01:14:52

回答

1

你可以做這樣的事情...使用命名空間的庫

HTML頁面:

<html> 
<head> 
    <title>javascript namespacing</title> 
    <script src="dashboard.js" type="text/javascript"></script> 
    <script src="ajax.js" type="text/javascript"></script> 
    <script src="retrieve_content.js" type="text/javascript"></script> 
    <script type="text/javascript"> 
     alert(Dashboard.Ajax.Post()); 
     alert(Dashboard.RetrieveContent.RefreshSalespersonPerformanceContent()); 
     Dashboard.RetrieveContent.Settings.Timeout = 1500; 
     alert(Dashboard.RetrieveContent.Settings.Timeout); 
    </script> 
</head> 

<body> 
    whatever... 
</body> 

</html> 

Dashboard.js:

(function(window, undefined){ 
    var dashboard = {}; 
    window.Dashboard = dashboard; 
})(window); 

Ajax.js:

(function(){ 
    var ajax = {}; 
    ajax.Post = function() { return "Posted!" }; 
    window.Dashboard.Ajax = ajax 
})(); 

Retrieve_Content.js:

(function(){ 
    var retrieveContent = {}; 
    retrieveContent.RefreshSalespersonPerformanceContent = function() { 
     return "content retrieved" 
    }; 


    var _contentType; 
    var _timeout; 
    retrieveContent.Settings = { 
     "ContentType": function(contentType) { _contentType = contentType; }, 
     "ContentType": function() { return _contentType; }, 
     "Timeout": function(timeout) { _timeout = timeout; }, 
     "Timeout": function() { return _timeout; } 
    }; 

    window.Dashboard.RetrieveContent = retrieveContent; 

})(); 

的Dashboard.js作爲起點下的所有命名空間。其餘的都在各自的文件中定義。在Retrieve_Content.js中,如果需要,我在Settings的基礎上添加了一些額外的屬性,以說明如何做到這一點。

+0

儘管'retrieve_content.js'將在Dashboard.js後加載並解析,但並不能保證。如果任何相關庫在Dashboard.js加載之前加載,那麼分配將失敗。 – 2010-08-05 04:51:29

+1

一般而言'Dashboard.js'將首先被加載和解析,但是,不能保證。 'Dashboard'對象可以在賦值之前進行檢查,並且可以在存在時進行創建,但是這需要'retrieve_content.js'和'ajax.js'中的一些重複代碼。 OP的單獨文件要求讓我看到上述情況。 – ironsam 2010-08-05 05:31:04

4

Yahoo Namespace函數正是爲這個問題而設計的。

補充:

功能的​​可用。你可以將它複製到你自己的代碼中,如果你想要的話,將YAHOO的根改爲其他的東西等等。

9

你只需要確定你的命名空間對象是否已經被創建。像這樣的東西會工作:

(function() { 
    // private vars can go in here 


    Dashboard = Dashboard || {}; 
    Dashboard.Ajax = { 
     Post: function() { 
      ... 
     } 
    }; 
})(); 

而且RetrieveContent文件將被類似地定義。

+0

嗨,我試圖把我的代碼放入命名空間,但我有一個問題:我有很多的JavaScript文件,我應該然後添加'Dashboard = Dashboard || {};'(如果這將是我的名字空間)在每個文件?其次,我是否必須將每個變量前綴爲Dashboard.x而不是x,或者不必要,因爲每個變量都位於相同的命名空間中? – Michel 2016-04-06 15:13:33

3

如果您想使用或檢查預先烘焙的(即測試過的)解決方案,有幾個庫已經提供了這種功能。

最簡單和最無bug一個獲得與去大概是jQuery.extend,與deep參數設置爲true。 (我之所以說這是無缺陷的原因並不是因爲我認爲jQuery.extend比其他任何庫有更少的bug,而是因爲它提供了一個明確的選項,可以將屬性從發送者深層複製到接收者 - 大部分其他庫明確不提供。這將防止許多難以診斷的錯誤在您的程序後出現,因爲您使用淺拷貝extend,現在有功能在您不期望它們的上下文中執行(如果你知道你在設計你的方法時如何擴展你的基礎庫,這應該不成問題)。

1

我相信模塊模式可能正好在你的衚衕裏。關於不同模塊模式的文章

http://www.adequatelygood.com/2010/3/JavaScript-Module-Pattern-In-Depth

+0

只有鏈接的答案是沒有用的。這裏應該有足夠的解釋。問題是如何在來自兩個不同位置的命名空間中定義對象 – 2012-02-13 18:10:59

+1

@JuanMendes:文章解釋了這一點。幾個最熱門的答案基本上只是鏈接。此外,這已經超過一年半了。 – 2012-02-13 19:17:19

+0

我從來沒有真正發現模塊模式適合命名空間。名稱空間不是「可重用」代碼塊(儘管NS的單個部分可能是)。對象文字對我來說一直效果不錯。 – 1nfiniti 2013-07-29 20:55:19

3

隨着NS對象的創建,你應該能夠從任何地方添加到它。儘管您可能想要嘗試var NS = NS || {};以確保NS對象存在並且不會被覆蓋。

// NS is a global variable for a namespace for the app's code 
var NS = NS || {}; 

NS.Obj = (function() { 

    // Private vars and methods always available to returned object via closure 
    var foo; // ... 

    // Methods in here are public 
    return { 
    method: function() { 

    } 
    }; 

}()); 
1

我強烈建議你使用這個技巧:

https://github.com/mckoss/namespace

namespace.lookup('com.mydomain.mymodule').define(function (ns) { 
    var external = namespace.lookup('com.domain.external-module'); 

    function myFunction() { 
    ... 
    } 

    ... 

    ns.extend({ 
    'myFunction': myFunction, 
    ... 
    }); 
}); 
我一直在使用這個模式來幾年

;我希望更多的圖書館會做同樣的事情;這讓我更容易在我的不同項目中共享代碼。

7

Here是關於JavaScript中各種「模塊模式」的很好的文章。關於如何擴充模塊或名稱空間以及維護跨文件私有狀態,有一個很好的小節。也就是說,單獨文件中的代碼將按順序執行,並在執行後正確地增加名稱空間。

我還沒有徹底探索過這種技術,所以沒有承諾......但這裏是基本的想法。

dashboard.js

(function(window){ 

    var dashboard = (function() { 
     var my = {}, 
      privateVariable = 1; 

     function privateMethod() { 
      // ... 
     } 

     my.moduleProperty = 1; 
     my.moduleMethod = function() { 
      // ... 
     }; 

     return my; 
    }()); 

    window.Dashboard = dashboard; 
})(window); 

dashboard.ajax.js

var dashboard = (function (my) { 
    var _private = my._private = my._private || {}, 
     _seal = my._seal = my._seal || function() { 
      delete my._private; 
      delete my._seal; 
      delete my._unseal; 
     }, 
     _unseal = my._unseal = my._unseal || function() { 
      my._private = _private; 
      my._seal = _seal; 
      my._unseal = _unseal; 
     }; 

    // permanent access to _private, _seal, and _unseal 

    my.ajax = function(){ 
     // ... 
    } 

    return my; 
}(dashboard || {})); 

dashboard.retrieveContent。JS

var dashboard = (function (my) { 
    var _private = my._private = my._private || {}, 
     _seal = my._seal = my._seal || function() { 
      delete my._private; 
      delete my._seal; 
      delete my._unseal; 
     }, 
     _unseal = my._unseal = my._unseal || function() { 
      my._private = _private; 
      my._seal = _seal; 
      my._unseal = _unseal; 
     }; 

    // permanent access to _private, _seal, and _unseal 

    my.retrieveContent = function(){ 
     // ... 
    } 

    return my; 
}(dashboard || {})); 
+0

請問您能解釋一下如何訪問在另一個文件中聲明的私有變量?如果我要調用dashboard._seal(),那麼更具體的說明,dashboard._unseal()如何讓我再次訪問私有? – 2015-05-30 08:55:40

0

bob.js可以定義(其中包括)您的命名空間的幫助:

bob.ns.setNs('Dashboard.Ajax', { 

    Post: function() { /*...*/ } 
}); 

bob.ns.setNs('Dashboard.RetrieveContent', { 

    RefreshSalespersonPerformanceContent: function() { /*...*/ } 
}); 
1

我寫了這個功能來簡化創建命名空間。瑪貝它會幫助你。

function ns(nsstr) { 
    var t = nsstr.split('.'); 
    var obj = window[t[0]] = window[t[0]] || {}; 
    for (var i = 1; i < t.length; i++) { 
     obj[t[i]] = obj[t[i]] || {}; 
     obj = obj[t[i]]; 
    } 
} 

ns('mynamespace.isawesome.andgreat.andstuff'); 
mynamespace.isawesome.andgreat.andstuff = 3; 

console.log(mynamespace.isawesome.andgreat.andstuff); 
0

實現:

namespace = function(packageName) 
{ 
    // Local variables. 
    var layers, layer, currentLayer, i; 

    // Split the given string into an array. 
    // Each element represents a namespace layer. 
    layers = packageName.split('.'); 

    // If the top layer does not exist in the global namespace. 
    if (eval("typeof " + layers[0]) === 'undefined') 
    { 
     // Define the top layer in the global namesapce. 
     eval(layers[0] + " = {};"); 
    } 

    // Assign the top layer to 'currentLayer'. 
    eval("currentLayer = " + layers[0] + ";"); 

    for (i = 1; i < layers.length; ++i) 
    { 
     // A layer name. 
     layer = layers[i]; 

     // If the layer does not exist under the current layer. 
     if (!(layer in currentLayer)) 
     { 
      // Add the layer under the current layer. 
      currentLayer[layer] = {}; 
     } 

     // Down to the next layer. 
     currentLayer = currentLayer[layer]; 
    } 

    // Return the hash object that represents the last layer. 
    return currentLayer; 
}; 


結果:

namespace('Dashboard.Ajax').Post = function() { 
    ...... 
}; 

namespace('Dashboard.RetrieveContent').RefreshSalespersonPerformanceContent = function() { 
    ...... 
}; 


GI ST:

namespace.js

相關問題