Как создать пространство имен в JavaScript, чтобы мои объекты и функции не перезаписывались другими объектами и функциями с такими же именами? Я использовал следующее:
if (Foo == null || typeof(Foo) != "object") { var Foo = new Object();}
Есть ли более элегантный или лаконичный способ сделать это?
javascript
namespaces
javascript-namespaces
Скотт МакКензи
источник
источник
Ответы:
Мне это нравится:
источник
MyApp
, например,MyApp.Views.Profile = {}
а неMyApp.users = {}
иMyViews.Profile = {}
. Не обязательно, чтобы была только два уровня глубины.Я использую подход, найденный на сайте Enterprise jQuery :
Вот их пример, показывающий, как объявлять частные и публичные свойства и функции. Все сделано как самоисполняющаяся анонимная функция.
Так что если вы хотите получить доступ к одному из публичных участников, вы просто идете
skillet.fry()
илиskillet.ingredients
.Что действительно круто, так это то, что теперь вы можете расширить пространство имен, используя точно такой же синтаксис.
Третий
undefined
аргументисточник
undefined
аргумент является источником переменной значенияundefined
. При работе со старыми стандартами браузеров / javascript (ecmascript 5, javascript <1.8.5 ~ firefox 4) переменная global-scope доступнаundefined
для записи, поэтому любой может переписать ее значение. Добавление третьего, дополнительного аргумента, который вы не передаете, делает его ценнымundefined
, поэтому вы создавали область имен,undefined
которая не будет перезаписываться внешними источниками.window.skillet = window.skillet || {}
заключается в том, что он позволяет нескольким сценариям безопасно добавлять одно и то же пространство имен, когда они заранее не знают, в каком порядке они будут выполняться. Это может быть полезно либо в том случае, если вы хотите иметь возможность произвольно переупорядочивать включения в сценарии, не нарушая код, либо если вы хотите загружать сценарии асинхронно с атрибутом async и, таким образом, не можете гарантировать порядок выполнения. См. Stackoverflow.com/questions/6439579/…Другой способ сделать это, который я считаю немного менее строгим, чем форма литерала объекта, заключается в следующем:
Вышеприведенный пример очень похож на шаблон модуля и , нравится вам это или нет , он позволяет вам выставлять все свои функции как общедоступные, избегая при этом жесткой структуры литерала объекта.
источник
ns().publicFunction()
, то есть ...ns.publicFunction()
работает.new
слово передfunction
ключевым словом. По сути, он объявляет анонимную функцию (и как функцию, а также конструктор), а затем немедленно вызывает ее как конструктор, используяnew
. Таким образом, последнее значение, которое хранится внутри,ns
является (уникальным) экземпляром этого анонимного конструктора. Надеюсь, это имеет смысл.Да. Например:
тогда вы можете иметь
источник
var your_namespace = your_namespace = your_namespace || {}
Я обычно строю это в замыкании:
Мой стиль за эти годы слегка изменился с тех пор, как я написал это, и теперь я нахожу, что пишу закрытие вот так:
Таким образом, я считаю, что общедоступный API и его реализация легче понять. Думайте о выражении return как о публичном интерфейсе к реализации.
источник
MYNS.subns = MYNS.subns || {}
??var foo = function
иfunction foo
похожи, будучи приватными; из-за динамически типизируемого характера JavaScript последний немного быстрее, поскольку пропускает несколько инструкций в конвейерах большинства интерпретаторов. С помощьюvar foo
, система типов должна вызываться, чтобы выяснить, какой тип назначается для упомянутой переменной, в то времяfunction foo
как система типов автоматически знает, что это функция, поэтому пара вызовов функции пропускается, что приводит к меньшему количеству вызовов инструкций процессора, таких какjmp
,pushq
,popq
, и т.д., что приводит к более короткому трубопроводу центрального процессора.function foo
синтаксис более читабелен. И мне все еще нравится моя версия.Поскольку вы можете писать разные файлы JavaScript, а затем объединять или не объединять их в приложении, каждый должен иметь возможность восстанавливать или создавать объект пространства имен без ущерба для работы других файлов ...
Один файл может использовать пространство имен
namespace.namespace1
:Другой файл может использовать пространство имен
namespace.namespace2
:Эти два файла могут жить вместе или отдельно, не сталкиваясь.
источник
Вот как Стоян Стефанов делает это в своей книге « Шаблоны JavaScript», которую я нахожу очень хорошей (она также показывает, как он делает комментарии, которые позволяют автоматически генерировать документацию API, и как добавить метод в прототип пользовательского объекта):
источник
Я использую этот подход:
Внешний код может быть:
источник
ns = ns || {}
может показаться более оборонительным, оно может привести к другим неожиданным результатам.Это продолжение ссылки user106826 на Namespace.js. Кажется, проект перешел на GitHub . Теперь это кузнец / namespacedotjs .
Я использовал этот простой помощник JavaScript для своего крошечного проекта, и пока он кажется легким, но достаточно универсальным для обработки пространства имен и загрузки модулей / классов. Было бы здорово, если бы это позволило мне импортировать пакет в пространство имен по своему выбору, не только в глобальное пространство имен ... вздох, но это не главное.
Это позволяет вам объявить пространство имен, а затем определить объекты / модули в этом пространстве имен:
Другой вариант - объявить пространство имен и его содержимое сразу:
Дополнительные примеры использования смотрите в файле example.js в источнике .
источник
Образец:
Вы можете опционально объявить
local
переменную,same
например, likeself
и assign,local.onTimeout
если вы хотите, чтобы она была закрытой.источник
Вы можете объявить простую функцию для предоставления пространства имен.
источник
Если вам нужна частная сфера:
иначе, если вы никогда не будете использовать частную область:
источник
Шаблон Module изначально был определен как способ обеспечить как частную, так и публичную инкапсуляцию для классов в традиционной разработке программного обеспечения.
При работе с шаблоном Module нам может быть полезно определить простой шаблон, который мы используем для начала работы с ним. Вот тот, который охватывает пространство имен, публичные и частные переменные.
В JavaScript шаблон Module используется для дальнейшей эмуляции концепции классов таким образом, что мы можем включать как открытые / закрытые методы, так и переменные в один объект, таким образом защищая определенные части от глобальной области видимости. Это приводит к уменьшению вероятности конфликта имен наших функций с другими функциями, определенными в дополнительных сценариях на странице.
преимущества
почему шаблон модуля является хорошим выбором? Начнем с того, что для разработчиков, которые исходят из объектно-ориентированного фона, он намного чище, чем идея истинной инкапсуляции, по крайней мере с точки зрения JavaScript.
Во-вторых, он поддерживает личные данные - поэтому в шаблоне Module открытые части нашего кода могут касаться закрытых частей, однако внешний мир не может касаться закрытых частей класса.
Недостатки
Недостатки шаблона Module заключаются в том, что, поскольку мы по-разному обращаемся как к публичным, так и к закрытым членам, когда мы хотим изменить видимость, мы фактически должны вносить изменения в каждое место, где использовался член.
Мы также не можем получить доступ к закрытым членам в методах, которые добавляются к объекту позже . Тем не менее, во многих случаях шаблон модуля по-прежнему весьма полезен и при правильном использовании, безусловно, может улучшить структуру нашего приложения.
Выявление шаблона модуля
Теперь, когда мы немного более знакомы с шаблоном модуля, давайте взглянем на слегка улучшенную версию - шаблон модуля выявления Кристиана Хайльмана.
Паттерн «Модуль раскрытия» появился, когда Хейлманн был разочарован тем, что ему пришлось повторять имя основного объекта, когда мы хотели вызвать один открытый метод из другого или получить доступ к публичным переменным. Ему также не нравилось требование к модулю шаблона о необходимости переключения возражать против буквального обозначения вещей, которые он хотел обнародовать.
Результатом его усилий стал обновленный шаблон, в котором мы просто определяем все наши функции и переменные в частной области и возвращаем анонимный объект с указателями на частную функциональность, которую мы хотели раскрыть как открытую.
Пример использования шаблона «Модуль раскрытия» можно найти ниже.
преимущества
Этот шаблон позволяет синтаксису наших сценариев быть более согласованным. Это также делает более ясным в конце модуля, какие из наших функций и переменных могут быть доступны публично, что облегчает читабельность.
Недостатки
Недостатком этого шаблона является то, что если частная функция ссылается на открытую функцию, эта открытая функция не может быть переопределена, если требуется исправление. Это связано с тем, что частная функция будет продолжать ссылаться на частную реализацию, и шаблон не применяется к открытым членам, только к функциям.
Члены открытого объекта, которые ссылаются на закрытые переменные, также подчиняются примечаниям правила no-patch выше.
источник
Я создал пространство имен которое вдохновлено модулями Эрланга. Это очень функциональный подход, но именно так я сейчас пишу свой код JavaScript.
Это дает закрытию глобальное пространство имен и предоставляет определенный набор функций внутри этого замыкания.
источник
После переноса нескольких моих библиотек в разные проекты и необходимости постоянно менять пространство имен верхнего уровня (со статическим именем), я переключился на использование этой небольшой вспомогательной функции (с открытым исходным кодом) для определения пространств имен.
Описание преимуществ в моем блоге . Вы можете получить исходный код здесь .
Одним из преимуществ, которые мне действительно нравятся, является изоляция между модулями в отношении порядка загрузки. Вы можете обратиться к внешнему модулю ДО того, как он будет загружен. И ссылка на объект, которую вы получите, будет заполнена, когда код станет доступен.
источник
Я использую следующий синтаксис для пространства имен.
jsfiddle: http://jsfiddle.net/rpaul/4dngxwb3/1/
источник
Я опоздал на вечеринку на 7 лет, но 8 лет назад проделал немалую работу:
Важно иметь возможность легко и эффективно создавать несколько вложенных пространств имен, чтобы сохранить сложное веб-приложение организованным и управляемым, соблюдая при этом глобальное пространство имен JavaScript (предотвращая загрязнение пространства имен), и не допуская при этом ни одного существующего объекта в пути к пространству имен. ,
Исходя из вышесказанного, это было мое решение около 2008 года:
Это не создает пространство имен, но предоставляет функцию для создания пространств имен.
Это может быть сжато до миниатюрной однострочной:
Пример использования:
Или как одно утверждение:
Либо тогда выполняется как:
Если вам не нужна поддержка устаревших браузеров, обновите версию:
Теперь я бы опасался разоблачения
namespace
самого глобального пространства имен. (Жаль, что базовый язык не дает нам этого!) Поэтому я обычно использую это сам в закрытии, например:В больших приложениях это нужно определить только один раз в начале загрузки страницы (для клиентских веб-приложений). Дополнительные файлы могут затем повторно использовать функцию пространства имен, если они сохранены (включены как «необязательные» в приведенном выше). В худшем случае, если эта функция будет повторно объявлена несколько раз - это всего лишь несколько строк кода и меньше, если минимизировать.
источник
Я думаю, что вы все используете слишком много кода для такой простой проблемы. Для этого не нужно делать репо. Вот функция одной строки.
Попробуй это :
источник
Мне нравится решение Jaco Pretorius, но я хотел сделать ключевое слово this более полезным, указав его на объект модуля / пространства имен. Моя версия сковороды:
источник
В последнее время мой любимый шаблон стал таким:
Конечно, return может быть в конце, но если за ним следуют только объявления функций, гораздо проще увидеть, что такое пространство имен и какой API предоставляется.
Шаблон использования функциональных выражений в таких случаях приводит к невозможности узнать, какие методы предоставляются, не просматривая весь код.
источник
namespace.a();
Если вы используете Makefile, вы можете сделать это.
Я предпочитаю использовать Makefile в любом случае, когда доберусь до 1000 строк, потому что могу эффективно закомментировать большие участки кода, удалив одну строку в make-файле. Это позволяет легко возиться с вещами. Кроме того, с помощью этой техники пространство имен появляется в прелюдии только один раз, поэтому его легко изменить, и вам не нужно повторять его внутри кода библиотеки.
Скрипт оболочки для живой разработки в браузере при использовании make-файла:
Добавьте это как задачу make «go», и вы можете «сделать go», чтобы ваша сборка обновлялась по мере написания кода.
источник
Довольно продолженный ответ Ionu G. Stan, но показывающий преимущества незагроможденного кода с помощью
var ClassFirst = this.ClassFirst = function() {...}
, который использует преимущества замкнутой области JavaScript для уменьшения загромождения пространства имен для классов в одном и том же пространстве имен.Вывод:
источник
Я написал другую библиотеку пространств имен, которая работает немного больше, чем пакеты / модули на других языках. Это позволяет вам создавать пакет кода JavaScript и ссылаться на этот пакет из другого кода:
Файл hello.js
Файл Example.js
Только второй файл должен быть включен в страницу. Его зависимости (файл hello.js в этом примере) будут автоматически загружены, а объекты, экспортированные из этих зависимостей, будут использованы для заполнения аргументов функции обратного вызова.
Вы можете найти соответствующий проект в Пакеты JS .
источник
Мы можем использовать его независимо таким образом:
источник
Моя привычка - использовать функцию myName () в качестве хранилища свойств, а затем var myName в качестве держателя метода.
Достаточно ли это законно или нет, бей меня! Я все время полагаюсь на свою логику PHP, и все просто работает. : D
if (this !== that) myObj.fName1(); else myObj.fName2();
Ссылка на это: JavaScript: Создание объекта с Object.create ()
источник
В JavaScript нет предопределенных методов для использования пространств имен. В JavaScript мы должны создавать свои собственные методы для определения пространств имен. Вот процедура, которой мы следуем в технологиях Oodles.
Зарегистрируйте пространство имен. Ниже приведена функция регистрации пространства имен.
Чтобы зарегистрировать пространство имен, просто вызовите вышеуказанную функцию с аргументом в качестве пространства имен, разделенного
'.'
(точка). Например, пусть ваше приложение называется oodles. Вы можете сделать пространство имен следующим методомВ основном это создаст вашу структуру NameSpaces как ниже в backend:
В приведенной выше функции вы зарегистрировали пространство имен с именем
"oodles.HomeUtilities"
и"oodles.GlobalUtilities"
. Чтобы вызвать эти пространства имен, мы создаем переменную, т.е. var$OHU
и var$OGU
.Эти переменные - не что иное, как псевдоним для инициализации пространства имен. Теперь, когда бы вы ни объявили принадлежащую
HomeUtilities
вам функцию, она будет объявлена следующим образом:Выше приведена инициализация имени функции, и она помещена в пространство имен
$OHU
. и вызывать эту функцию в любом месте файлов сценария. Просто используйте следующий код.Аналогично с другими пространствами имен.
Надеюсь, поможет.
источник
JavaScript не поддерживает пространство имен по умолчанию. Таким образом, если вы создаете какой-либо элемент (функцию, метод, объект, переменную), он становится глобальным и загрязняет глобальное пространство имен. Давайте рассмотрим пример определения двух функций без пространства имен,
Он всегда вызывает определение второй функции. В этом случае пространство имен решит проблему конфликта имен.
источник