Предпочтительная техника для пространства имен javascript - PullRequest
4 голосов
/ 01 июля 2011

Мой код превратится в беспорядок, если я не начну использовать какую-то технику пространства имен. Я относительно новичок в программировании больших проектов javascript, но имею значительный опыт работы с системным программированием на C ++ / java / python и т. Д.

В основном я пытаюсь определить, какой метод является предпочтительным для создания пространств имен javascript, и каковы плюсы / минусы для каждого метода.

Например, я мог бы использовать любой из следующих трех методов:

var proj.lib.layout = {
  "centreElem":     
  function (elem, W, H){

  },

  "getAbsolutePosition":
  function (elem){

  }
};

OR

var proj.lib.layout = {};
(function(){
  var l = proj.lib.layout;

  l.centreElem = function (elem, winW, winH){
    ..
  }

  l.getAbsolutePosition = function (elem){
    ..
  }
})();

OR

var proj.lib.layout = new function(){
  function centreElem(elem, W, H){
    ..
  }

  function getAbsolutePosition(elem){
    ..
  }

  this.centreElem          = centreElem;
  this.getAbsolutePosition = getAbsolutePosition;
} ();

Есть и другие способы сделать это слишком очевидно, но это были первые, что я видел и думал. Кто-нибудь может сказать, что есть «лучшая» техника, или, по крайней мере, указать мне на некоторые плюсы / минусы, из которых я могу оценить, что лучше для меня?

Ответы [ 4 ]

3 голосов
/ 01 июля 2011

Обратите внимание, что вам необходимо создать все промежуточные объекты, прежде чем вы сможете назначить подобъекту подобный этому:

window.one.two.three = {}; // fails
window.one = { two: { three: {} } };

Подумайте о написании метода пространства имен, чтобы вы могли унифицировать код пространства имен. Например:

window.proj = {};
// n - {String} - A string representing a namespace to create on proj
// returns an object you can assign values to
window.proj.namespace = function(n) { /* ... */ };

(function(NS) {
    NS.myMethod = function() {};
    NS.myOtherMethod = function() {};
    NS.myProperty = "FOO";
})(proj.namespace('lib.layout'));

assert(proj.lib.layout.myProperty === "FOO");
1 голос
/ 01 июля 2011

Мой предпочтительный метод состоит в том, чтобы в качестве пространства имен, в котором содержались все другие объекты, был бы один объект (имя которого обычно короткое, 2-3 символа и все в верхнем регистре).

Метод, показанный ниже (который наиболее соответствует вашему второму примеру), также показывает, как скрыть любые частные функции:

// In this example the namespace is "QP"
if (!QP) {
    var QP = {};
};

// Define all objects inside an closure to allow "private" functions
(function() {

     QP.examplePublicFunction = function() {
         ...
     }

     function examplePrivateFunction() {
         ...
     }

})();

Этот метод используется рядом других библиотек JavaScript, например json2.js

Я никогда не чувствовал необходимости разделять свои пространства имен на подпространства.

0 голосов
/ 01 июля 2011

В библиотеке Google Closure Javascript используется этот стиль (который совсем не похож на ваши примеры)

goog.math.clamp = function(value, min, max) {
  return Math.min(Math.max(value, min), max);
};

Я бы придерживался этого простого стиля.Не беспокойтесь о автоматически выполняющихся оболочках анонимных функций.Тот, что в вашем примере, на самом деле ничего полезного не делает.

0 голосов
/ 01 июля 2011

В основном все три примера используют одну и ту же технику «пространства имен», то есть создают базовый объект (ваше пространство имен) и затем дополняют его своими функциями.

обычно корневое пространство имен пишется заглавными буквами:1003 *

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

Затем вы можете добавить функциональность к этому базовому объекту различными способами.В вашем коде вы показываете три из них, но каждый из них приводит к одинаковому результату, вы можете вызвать эти две функции:

proj.lib.layout.centreElem(elem, W, H);
proj.lib.layout. getAbsolutePosition(elem);
...