2010-08-05 126 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

相关问题