Довольно хорошо известно в JavaScript, что объявление переменных в глобальной области видимости является плохой вещью. Так кодируют, я склонен продолжать работать, содержит namespaced JavaScript.
Кажется, существует два разных подхода, проявленные к этому -
$.myCarouselfunction
MyApplication.myCarouselFunction
Я хотел знать, существует ли лучшее решение или если они имеют тенденцию встречаться где-нибудь близко с точки зрения за и против.
Причина для меня лично решающий не пойти с библиотекой до сих пор для Seperation / Изоляция / Отсутствие конфликта с кодом библиотеки и потенциальными плагинами, которые, вероятно, совместно используют то пространство имен. Существует ли больше к этому, что я не рассматриваю?
Я предпочитаю добавлять собственный код в библиотеку самостоятельно. Основная причина этого в том, что семантика использования остается согласованной во встроенном коде и моем пользовательском коде. При этом я не могу придумать никаких технических преимуществ или недостатков этого подхода. Я думаю, что ваше беспокойство по поводу конфликтов обосновано, хотя, вероятно, маловероятно (если вы получите компонент / модуль, который конфликтует с одной из ваших пользовательских функций, скорее всего, это произойдет из-за того, что вы заменяете свой код чужим).
Я думаю, что наиболее важным при выборе такого рода вещей является семантика .
Ваша функция / класс расширяется или зависит от конкретной функции библиотеки? Поместите ее в пространство имен библиотеки.
Является ли ваша функция / класс независимой от библиотеки? В этом случае лучше поместить ее в настраиваемое пространство имен. Это позволяет повторно использовать ваш код за пределами библиотеки, с которой вы его изначально использовали.
Правильный выбор зависит от вашей целевой среды. Вы выбираете между двумя пространствами имен, оба из которых могут произвольно загромождаться. Если вы считаете, что более вероятно, что вы столкнетесь с конфликтом в пространстве имен библиотеки, вам следует использовать пространство имен window. Если вы считаете, что пространство имен окна с большей вероятностью будет загромождено, выберите пространство имен библиотеки.
В любом случае вы обычно должны создать только одно «глобальное» имя. Другими словами, если вы собираетесь поместить свою функцию в пространство имен библиотеки, лучше не называть ее $ .myFn. Назовите его $ .yaya3.myFn, а затем кешируйте локальную ссылку на него в любом контексте, где вы вызываете myFn несколько раз.
Один из лучших способов обращения к вашей функции - передать пространство имен, в котором она находится, в качестве аргумента анонимной функции:
(function (yaya3) {
var myFn = yaya3.myFn;
myFn("frobnard!");
}(window.yaya3)); // you could instead pass $.yaya3 or YUI.namespace("yaya3") here
Это значительно упрощает, если вы обнаружите, что вам нужно перейти к другое пространство имен.
Лично мне нравится такой подход:
(function(namespace) {
function myPrivateFunction(){};
namespace.myPublicFunction = function(){};
})($); // passing the $ namespace, but if it clutters,
// we can change it to something else
Если вы когда-либо пытались задействовать более одной библиотеки, используя одно и то же пространство имен, может быть удивительно, насколько вероятны коллизии, и это может быть довольно неприятно, поскольку такого рода ошибки часто возникают неожиданными и трудными для отладки способами.Я думаю, что ваша интуиция относительно коллизий верна, и что самое важное соображение относительно того, следует ли определять свое собственное пространство имен или повторно использовать чужое, - это уважать владение пространством имен. Это означает, что если вы не контактируете с людьми, которые поддерживают другое пространство имен, и они не знают, что вы делаете, рекомендуется использовать собственное пространство имен.
Если вы все же решите проигнорировать совет по владению пространством имен и определить API в существующем пространстве имен (для семантики или чего-то еще), нужно рассмотреть одну вещь - использовать функцию экспорта для обнаружения ошибок. По сути, вы можете сначала определить что-то в своем собственном пространстве имен, а затем экспортировать это в целевое пространство имен в следующих строках:
MyApplication.exportName = function(objToExportTo, name, obj) {
if (objToExportTo[name] === undefined) {
objToExportTo[name] = obj;
} else {
// Possibly assert!
}
};
MyApplication.myCarouselFunction = function() { ... };
MyApplication.exportName($, 'myCarouselFunction', MyApplication.myCarouselFunction);