Пространство имен Javascript - это хороший шаблон? - PullRequest
4 голосов
/ 08 марта 2011

Цели ...

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

То, что я хочу сделать здесь, - это хранить переменные, которые мне нужны для моего пользовательского интерфейса (в данном случае текущего времени в UTC), чтобы они не были в глобальном объекте. Я также хочу предоставить некоторые конкретные функции. Это должно быть доступно на каждой странице без каких-либо примеров ...

Теперь я хочу, чтобы объект хранился в моей структуре пространства имен. Однако этот объект нужно будет создать несколько раз. Цель здесь - сохранить это внутри моей структуры, но позволить создавать ее столько раз, сколько мне нужно. Это выглядит следующим образом:

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

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

И это пример кода для создания экземпляра объекта ...

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

Это хороший шаблон?

Ответы [ 4 ]

1 голос
/ 08 марта 2011

Разумно, чтобы вещи определялись в пространстве имен 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.На самом деле это не обязательно.

Мое личное предпочтение - всегда использовать замыкания для создания частного пространства имен и переносить что-либо в глобальное / общее пространство имен, где это необходимо.Это уменьшает глобальную видимость / кластер до минимума.

0 голосов
/ 12 июля 2013

Используя анонимную самореализующуюся функцию, вы можете разрешить использование публичных и приватных атрибутов / методов.

Это шаблон, который мне нравится больше всего:

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

Узнал об этом из комментариев в этой статье .

0 голосов
/ 12 апреля 2013

Я пытался сделать похожую вещь:

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/

0 голосов
/ 08 марта 2011

Слегка указав вам немного в сторону, с пути вашего вопроса: Взгляните на YUI3 (http://developer.yahoo.com/yui/3/) - у вас нет (иметь) чего-либо в глобальном пространстве имен, вы получаете приватную песочницу. Отличная концепция, мне нравится эта библиотека и ее концепции (YUI3 , не говоря уже о старом YUI2.) Конечно, это просто, и вы можете сделать это тоже: динамический загрузчик модулей YUI3 загружает ваш модуль (файл (файлы) .js), создает песочницу (просто замыкание) и вызывает ваш обратный вызов, давая ему ручку для песочницы. Никакой другой код нигде не может получить доступ к этой песочнице и вашим собственным именам. В этой песочнице вы можете (и должны) использовать различные шаблоны инкапсуляции. Эта концепция YUI3 великолепна для гибридных приложений с сторонним кодом, особенно когда гибридные приложения становятся более динамичными по своей природе (например, инициируемые пользователем), а не просто интегрируют Google Maps или другие известные API-интерфейсы самими программистами.

...