4

目标...

  1. 从全局对象中删除变量、对象等。
  2. 消除碰撞的可能性。

首先,我实现了 Yahoo 命名空间代码(例如,注意我使用 ROOT 作为命名空间的根)...

        if (typeof ROOT == "undefined" || !ROOT) {
                var ROOT = {};
        }

        ROOT.namespace = function () {
            var a = arguments,
                o = null,
                i, j, d;
            for (i = 0; i < a.length; i = i + 1) {
                d = ("" + a[i]).split(".");
                o = ROOT;
                for (j = (d[0] == "ROOT") ? 1 : 0; j < d.length; j = j + 1) {
                    o[d[j]] = o[d[j]] || {};
                    o = o[d[j]];
                }
            }
            return o;
        }

现在我声明我的第一个命名空间......

ROOT.namespace("UI");

            ROOT.UI = {
                utc: 12345,
                getUtc: function() {
                    return this.utc;
                }
            }

我在这里要做的是保存我的 UI 所需的变量(在这种情况下是 UTC 的当前时间),以便它们不在全局对象上。我还想提供一些特定的功能。这应该在每个页面上都可用,无需任何实例化......

现在我想在我的命名空间结构中存储一个对象。但是,需要多次创建此对象。这里的目标是将其保留在我的结构中,但允许根据需要多次创建它。如下:

 ROOT.namespace("AirportFinder");
            ROOT.AirportFinder = function(){ 
                this.var1 = 99999;

                this.Display = function() {
                    alert(this.var1);
                }            
            }

这是实例化对象的示例代码......

        var test1 = new ROOT.AirportFinder();
        test1.Display();

这是一个好的模式吗?

4

4 回答 4

1

ROOT在命名空间或类似的东西上定义东西确实是合理的。

使用闭包也更好

(function() {
    var AirportFinder = function() { 
        this.var1 = 99999;
        this.Display = function() {
            alert(this.var1);
        }            
    };

    // do Stuff with local AirportFinder here.

    // If neccesary hoist to global namespace
    ROOT.AirportFinder = AirportFinder;
}());

如果他们不需要是全球性的。我自己使用别名($.foobar因为 jQuery 无论如何都是全局的)来存储任何全局数据。

恐怕我不能告诉你这个.namespace功能是做什么的。这不是真的必要。

我个人的偏好是始终使用闭包来创建私有命名空间,并将任何需要的东西提升到全局/共享命名空间。这将全局可见性/集群降至最低。

于 2011-03-08T10:32:08.243 回答
0

By using an anonymous self-executing function, you can allow for public and private attributes/methods.

This is the pattern I like the most:

(function ($, MyObject, undefined) {
  MyObject.publicFunction = function() {
      console.log("This is a public function!");
  };
  var privateFunction = function() {
    console.log("This is a private function!");
  };

  MyObject.sayStuff = function() {
    this.publicFunction();
    privateFunction();
    privateNumber++;
    console.log(privateNumber);
  };
  var privateNumber = 0;

  // You can even nest the namespaces
  MyObject.nestedNamespace = MyObject.nestedNamespace || {};      
  MyObject.nestedNamespace.logNestedMessage = function () {    
     console.log("Nested!!");
  };

}(jQuery, window.MyObject = window.MyObject || {}));

MyObject.sayStuff();
MyObject.nestedNamespace.logNestedMessage();
MyObject.publicFunction();

Learned about it from the comments in this article.

于 2013-07-11T23:27:20.560 回答
0

稍微把你指向一边,偏离你的问题:看看 YUI3 (http://developer.yahoo.com/yui/3/) - 你没有(拥有)任何东西在那里的全局命名空间中,您将获得一个私有沙箱。伟大的概念,我喜欢那个图书馆和它的概念(YUI3,不是在谈论旧的 YUI2)。它这样做的方式当然很简单,你也可以这样做:YUI3 的动态模块加载器加载你的模块(.js 文件),创建一个沙箱(只是一个闭包)并调用你的回调,给它一个沙盒的句柄。任何地方都没有其他代码可以访问该沙箱和您自己的名字。在该沙箱中,您可以(并且应该)继续使用各种封装模式。这个 YUI3 概念非常适合使用外来代码的 mashup,尤其是当 mashup 在本质上变得更加动态时(例如用户触发),而不是仅仅由程序员自己集成 Google Maps 或其他知名 API。

于 2011-03-08T11:13:02.570 回答
0

我试图做类似的事情:

var namespace = function(str, root) {
    var chunks = str.split('.');
    if(!root)
        root = window;
    var current = root;
    for(var i = 0; i < chunks.length; i++) {
        if (!current.hasOwnProperty(chunks[i]))
            current[chunks[i]] = {};
        current = current[chunks[i]];
    }
    return current;
};

// ----- USAGE ------

namespace('ivar.util.array');

ivar.util.array.foo = 'bar';
alert(ivar.util.array.foo);

namespace('string', ivar.util);

ivar.util.string.foo = 'baz';
alert(ivar.util.string.foo); 

试试看:http: //jsfiddle.net/stamat/Kb5xY/

博文:http ://stamat.wordpress.com/2013/04/12/javascript-elegant-namespace-declaration/

于 2013-04-12T13:15:14.607 回答