Здравствуйте коллеги.
Вот уже не первый год пишу на JavaScript и в голове кристаллизовались некоторые шаблоны, подходы и так далее, которые хочется выделить в некую библиотеку. Поэтому решил не спеша "выписывать" эти вещи в виде частей собственного фреймворка.
Создал для этого на GitHub репозиторий: https://github.com/rostislav-nikitin/SRD.JS.
Буду держать вас в курсе последних изменений.
SRD.Namespace
А сейчас хотелось бы немного рассказать о первенце - модуле ./Js/SRD.Namespace.js
Данный модуль позволяет создавать неймспейсы. Всем C#, Java программистам хорошо знакома эта концепция, которая позволяет удобно группировать код в смысловые множества. К сожалению (или к счастью) JavaScript не обладает встроенными возможностями управления неймспейсами. Поэтому почти каждый программист на JavaScript, решивший упорядочить свой код, или придумывает своё решение или берёт чьё то. Я решил предложить вам свой вариант.
На первый взгляд не понятно, зачем нужен какой-то дополнительный модуль ? Можно ведь просто написать var System = { Collections : {} };
А теперь представьте, что у вас несколько классов. Скажем: List, Hashtable, Stack, Queue, ... Один класс - один файл. Все они должны быть в одном неймспейсе с длинным именем. Скажем: System.Primitives.Collections. То есть в каждом файлы придётся делать следующие проверки:
if(typeof(System) === "undefined" || System === null) { System = {}; }
if(!("Primitives" in System)) { System.Primitives = {}; }
...
Можно короче:
if(!window.System) { window.System = {}; }
System.Primitives = System.Primitives || {};
...
Но тем не менее, гораздо удобнее и нагляднее написать:
ns("System.Primitives.Collections"); // This is clear code
Итак, подключив SRD.Namespace.js к себе в приложение, Вы автоматически получаете класс SRD.Namespace.
Данный класс содержит такие методы и свойства:
- public static object ns (string nsFullName) - создаёт все неймспейсы (если не были созданы до момента вызова) и возвращает ссылку на самый последний (в очерёдности слева на право). Под словом "все" подразумевается следующее. Во первых nsFullName - это имя неймспейса в таком формате: "NSName.NSName...NSName". Например "System.Collections". Так вот вызвав ns с параметром "System.Collections" - будет создано два объекта. Первый - это неймспейс с именем "System". Второй - это вложенный в него неймспейс с именем "Collections". Таким образом написав в коде System.Collections.List = function() {}; ошибке "'System' is undefined" не суждено будет случиться. А в неймспейсе "System.Collections" будет создан новый ключ List, которому будет соответствовать пустая функция. Если теперь выполнить ns("System.Collections.Specialized"), то как вы догадались неймспейсы "System" и "System.Collections" - никуда не денутся, как и содержащиеся в них классы. Просто будет создан ещё один неймспейс "System.Collections.Specialized" внутри "System.Collections"
- public static boolean isNs (object obj) - проверяет, является ли объект неймспейсом. Возвращает true - если объект неймспейс, в противном случае возвращает false
- public static boolean isNsExists (string nsFullName) - проверяет, существует ли неймспейс соответствующий указанному полному полному имени. Возвращает true - если неймспейс с таким полным именем существует, в противном случае возвращает false
- public string getName() - свойство, которое возвращает имя неймспейса. Например System.Collections.getName() вернёт строку "Collections"
- public string getFullName() - свойство, которое возвращает полное имя неймспейса (включает в себя имена всех родительских неймспейсов, разделённых точкой). Например System.Collections.getFullName() - вернёт строку "System.Collections"
- public boolean getIsNamespace() - свойств, которое возвращает true если инстанс является неймспейсом, в противном случае возвращает false
- public object getParentNamespace() - свойство, которое возвращает ссылку на "родительский" неймспейс относительно инстанса или null, если инстанс является корневым неймспейсом и не имеет предка
Кто-то из вас наверняка спросит, а откуда в JavaScipt ключевые слова: public, static и так далее ? Ни откуда. Я просто хотел показать, что метод ns например может быть вызван следующим образом: SRD.Namespace.ns(...) - то есть как статический, по отношению к классу SRD.Namespace. А getName() - как метод инстанса: someNs.getName().
Так же, все статические методы доступны из GlobalContext. То есть у себя в коде (если это например браузер и текущий контекст - window) вы можете просто написать: ns("SomeNsName.OtherNsName");
Больше примеров вы можете найти здесь: ./Examples/SRD.Namespace.Examples.htm
Критика, конструктивные пожелания и баг репорты приветствуются.
Отправляйте на e-mail: rostislav.nikitin@gmail.com