Javascript 命名空间 - 这是一个好的模式吗?

发布于 2024-10-20 14:08:01 字数 1531 浏览 2 评论 0原文

目标...

  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();

这是一个好的模式吗?

Objectives...

  1. Remove vars, objects etc from the global object.
  2. Remove possibility of collisions.

Firstly I implement the Yahoo namespace code (note for example purposes I am using ROOT as the root of my namespace)...

        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;
        }

Now I declare my 1st namespace...

ROOT.namespace("UI");

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

What I want to do here is to hold vars that I need for my UI (in this case the current time in UTC) so that they are not on the global object. I also want to provide some specific functionality. This should be available on every page without any sort of instanciation...

Now I want to have an object stored within my namespace structure. However, this object will need to be created multiple times. The objective here is to keep this inside my structure but allow it to be created as many times as I need. This is as follows:

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

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

And this is the sample code to instanciate the object...

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

Is this a good pattern?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

烂人 2024-10-27 14:08:01

在命名空间 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 函数的作用。这其实不是必要的。

我个人的偏好是始终使用闭包来创建私有名称空间,并在必要时将任何内容提升到全局/共享名称空间。这将全局可见性/集群降低到最低限度。

It is indeed reasonable to have things defined on a namespace ROOT or something alike.

It's also better to use closures

(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;
}());

If they don't need to be global. I myself use an alias ($.foobar because jQuery is global anyway) for storing any global data.

I'm afraid I can't tell you waht the .namespace function does. It's not really neccessary.

My personal preference is to always use closures to create a private namespace and hoist anything to the global/shared namespace where neccesary. This reduces the global visibility/cluster to a minimum.

谁的年少不轻狂 2024-10-27 14:08:01

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

Slightly pointing you a little to the side, off the path of your question:
Have a look at YUI3 (http://developer.yahoo.com/yui/3/) - you don't have (to have) anything in the global namespace there, you get a private sandbox. Great concept, I love that library and its conocepts (YUI3, not talking about old YUI2). The way it does that is of course simple and you could do that too: The dynamic module loader of YUI3 loads your module (.js file(s)), creates a sandbox (just a closure) and calls your callback, giving it a handle for the sandbox. No other code anywhere can gain access to that sandbox and your own names. Within that sandbox you can (and should) go on using the various encapsulation patterns. This YUI3 concept is great for mashups with foreign code, especially when mashups become more dynamic in nature (e.g. user triggered), instead of just integrating Google Maps or other well-known APIs by the programmers themselves.

我乃一代侩神 2024-10-27 14:08:01

我尝试做类似的事情:

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/

I tried to do a similar thing:

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); 

Try it out: http://jsfiddle.net/stamat/Kb5xY/

Blog post: http://stamat.wordpress.com/2013/04/12/javascript-elegant-namespace-declaration/

十秒萌定你 2024-10-27 14:08:01

通过使用匿名自执行函数,您可以允许公共和私有属性/方法。

这是我最喜欢的模式:

(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();

这篇文章的评论中了解到它

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文