Пространство имен в JavaScript
Как создать пространство имен в JavaScript
Я считаю, что пространство имен в JavaScript - одна из самых запутанных и достаточно сложно понимаемых тем. Именно поэтому я постарался разобраться с данным вопросом и изложил некоторые пояснения для тех, кто, как и я, встретил затруднения, проникаясь данной темой.
Итак, с помощью JavaScript мы создаем проекты. По мере того, как эти проекты растут и усложняются, растет и вероятность того, что какие-либо переменные или функции получат одинаковые имена, что, несомненно, приведет к определенным конфликтам.
Чтобы избежать таких неприятных событий, мы можем пользоваться пространствами имен, создающими локальные области видимости для наших переменных и функций. К сожалению, в отличие от многих других популярных языков программирования в JavaScript отсутствуют “классические” пространства имен. Данный факт приводит к необходимости искать альтернативные пути для того, чтобы получить сходный эффект. Наиболее популярным способом в JavaScript является реализация пространства имен через объект.
Ниже мы рассмотрим несколько, наиболее часто используемых подходов.
Прямое определение
var webApp = {}
webApp.id = 0;
webApp.next = function() {
return webApp.id++;
}
webApp.reset = function() {
webApp.id = 0;
}
Пример, приведенный выше, демонстрирует, что имена переменных id
и next
могут многократно безо всяких проблем использоваться во всем веб-приложении. Вместо того, чтобы создавать новые переменные, необходимые для реализации некоторых задач, посредством создания длинных имен, отягощенных определенным смысловым назначением: например, idOfWebApp
, мы создаем объект, которые содержит всю информацию о веб-приложении, отделяя имена переменных и функций от глобальной области видимости.
В нашем примере объект webApp
содержит одну переменную и 2 функции. Если мы напишем:
console.log(webApp.next());
результатом будет 0
.
Но если мы попробуем вызвать функцию next()
в глобальной области видимости проекта:
console.log(next());
получим ошибку:
Uncaught ReferenceError: next is not defined
так как данная функция существует только в пространстве имен объекта webApp
.
Объектные литералы
var webApp = {
id: 0,
next: function() {
return this.id++;
},
reset: function() {
this.id = 0;
}
}
В данном случае приведен, наиболее часто используемый синтаксис для определения локального пространства имен в JavaScript.
Паттерн “Модуль”
var webApp = (function() {
var id= 0;
return {
next: function() {
return id++;
},
reset: function() {
id = 0;
}
};
})();
А в этом примере все становится немного сложнее. Синтаксис понятен, но, что означают круглые скобки ()
?
Таким образом в JavaScript определяются самовызывающиеся функции (IIFE, Immediately-Invoked Function Expression, немедленно определяемые функциональные выражения):
(function (){
// some privat information is here
})();
Такие функции выполняются сразу же после их объявления и используются для решения разовых задач, не оставляя следов в глобальной области видимости. Однако, присвоив возвращаемому самовызываемой функцией объекту имя, мы получаем обычный объект со своей локальной областью видимости содержащихся в нем переменных и функций.
Почему паттерн “Модуль” лучше?
В отличие от метода объектных литералов паттерн “Модуль” содержит как публичные, так и приватные функции и переменные. Наличие приватных сущностей позволяет добавить проекту гибкости и обеспечить дополнительную конфиденциальность.
Заключение
Несомненно, паттерн “Модуль” должен использоваться в больших проектах. Объектные литералы следует использовать для решения несложных задач.
Спасибо за внимание.
По материалам статьи Himanshu Tiwari “Namespacing in JavaScript”.