Как определить глобальную функцию в express.js, без require
я могу назвать ее
Глобальная функция в express.js?
Ответ 1
"Как" достаточно просто:
global.fnName = function(){ return "hi"; }; // Andreas Hultgren answer
Но вам не нужен префикс global
; вещь о объекте global
...
fnName = function(){ return "hi"; }; // i.e. don't do: var name = function(){ ... };
console.log(fnName()); // this prints "hi"
console.log(global.fnName()); // this also prints "hi" - it was assigned to global.
"Без require
" - отдельное соображение: если вы не используете require
, не гарантирует, что ваши "глобалы" будут объявлены к моменту их использования. Он обеспечивает, среди прочего, порядок загрузки зависимостей.
"Почему я" и "Правильно ли это" - теперь скрытые вопросы, которые вы должны рассмотреть. В javascript принято, что глобальные переменные...
... следует зарезервировать для объектов, которые имеют общесистемную релевантность, и их следует назвать, чтобы избежать двусмысленности и минимизировать риск именования столкновений - Ангус Кролл, Namespacing в Javascript
то есть. global
true is Global: он используется каждым автором каждого плагина или библиотеки, которую вы втягиваете в свое приложение, а не только от вас. Именование коллизий между глобальными переменными прерывает ваше приложение. Это в равной степени относится к node.js.
Глобальные переменные также рассматриваются как как запах кода. В подробных разделах ниже вы увидите, что вы можете быстро попасть в проблему, используя глобальные переменные, и их действительно следует рассматривать как нечто, что подталкивает вас к инъекции зависимостей и/или пространств имен и модулей.
Node.js и выражения - глобальные вары и функции
Здесь хорошее правило: если вы загружаете его на веб-сервер или делитесь им с другими людьми, не используйте глобальные переменные.
global
допустимо в небольших "субботних дневных" приложениях в node.js с express.js, но, как правило, вызывает проблемы позже, если они будут приняты в производство. Поэтому:
- Модули и
exports
- лучшая практика. - Инъекция также должна использоваться для уменьшения связи между файлами javascript. Но во всех случаях вам обычно понадобится
require
, чтобы убедиться, что они существуют к тому моменту, когда они вам понадобятся: -
Вы должны действительно рассмотреть
app.locals
данные и/или функции промежуточного программного обеспечения, для всего, что связано с данными просмотра.// call this as a function with an input object to merge // the new properties with any existing ones in app.locals app.locals.({ sayHello: function() { return "hi"; } }); // now you can also use this in a template, like a jade template =sayHello()
Если вы создаете глобальные vars/functions для целей настройки конфигурации, все ниже применяются комментарии об пространствах имен, и появляются такие соглашения, как файлы config.json(по-прежнему использующие require
) для параметров, которые глобально доступны.
Глобальные переменные - простой случай
Достаточно просто объявить глобальную переменную в javascript, а для функции этот процесс ничем не отличается. Просто опустите ключевое слово var
, которое обычно заставляет локальную область в объявлении:
// app.js
blah = "boo";
sayHello = function(string toWho) { return "hello " + toWho; }
getVersion = function() { return "0.0.0.1"; }
// routes/main.js
console.log(blah); // logs: "boo"
console.log(global.blah); // logs: "boo"
console.log(sayHello("World")); // logs: "hello World"
console.log(global.sayHello("World")); // logs: "hello World"
console.log(getVersion()); // logs: "0.0.0.1"
Но что, если два отдельных плагина в вашем проекте используют глобальную функцию getVersion
- как вы получаете нужный номер версии? Кроме того, как вы гарантируете, что getVersion
существует до того, как он понадобится, или существует вообще?
Зачем нам нужен require
?
Чтобы процитировать nodejitsu docs встроенную функцию require
...
... это самый простой способ включить модули, которые существуют в отдельных файлах. Основная функциональность
require
заключается в том, что он читает файл javascript, выполняет файл и затем возвращает объектexports
"Итак", вы можете спросить: "require
просто обеспечивает включение module из другого файла??" Это лучше, чем это: вы можете сделать всю папку модулем, что упростит ваш код и проверит тестовый тест, он распознает различные расширения для файловые модули, а не только .js
, а будет выглядеть в различные папки. Конечно, также кэширует.
Итак, теперь, когда require
нашел ваш модуль, он обеспечивает выполнение кода внутри него и помещает созданные вами объекты в "пространство имен":
// module file ./myModule.js
exports.blah = "boo";
exports.sayHello = function(string toWho) { return "hello " + toWho; }
// routes/main.js
var demoModuleReference = require('./myModule.js');
console.log(demoModuleReference.blah); // logs: "boo"
console.log(demoModuleReference.sayHello("World")); // logs: "hello World"
В этом примере demoModuleReference
- это объект, который выглядит так:
{
blah: "foo",
sayHello: [Function]
}
Почему модули, а не глобальные переменные (a.k.a namespacing и "Global - новый частный" )?
Теперь кажется сложным? Неужели глобальные переменные проще? requires
обеспечивает следующее:
- Он обеспечивает упорядоченную загрузку зависимостей
- Он предотвращает конфликты имен переменных внутри
global
через объектexports
.
Это приложение на mankz.com(только хром или firefox) увлекательно. В зависимости от того, как вы используете свой js-код, вы, скорее всего, будете иметь конфликты имен имен в глобальной области. Конфликты имен происходят повсюду. Например, в браузере они могут поступать из расширений. node.js немного отличается, но с течением времени он становится все более и более расширяемым благодаря совместимым плагинам (например, вы можете загрузить jquery прямо сейчас, например). По мере добавления версий в рамки будут добавлены, а имена конфликтов в глобальном масштабе станут более вероятными. Мой последний запуск этого приложения в хроме показал более 1200 глобальных переменных пространства имен.
Пространства имен - почему?
Это глобальное загрязнение пространства имен было обнародовано в начале Дугласом Крокфордом через Эрика Мираглия в статье "Шаблон модуля JavaScript". Вкратце:
- Все объекты, которые должны использоваться между файлами js, действительно глобальны
- Итак, создайте объект пространства имен, который будет уникальным
- Назначить возвращаемое значение анонимной функции
- Добавьте в эту функцию частные методы и переменные
- Сделайте что-нибудь полезное с шаблоном
Пример:
ANDYBROWNSONICSUITE.BoomBox.SoundModule = function () {
var privateField = "can't touch this";
return {
play: function() {
console.log(privateField);
}
}
}
Почему это хорошо?
- Теперь вы только увеличили членов пространства имен
global
в мире на один, но этот член содержит как можно больше элементов. - Ваше приложение с гораздо меньшей вероятностью столкнется с другими пространствами имен
- Это шаблон, другие фреймворки ожидают, что вы его используете, чтобы правильно взаимодействовать с ними. В этой ссылке jQuery является плагином для браузера, но вы можете использовать его с node и, следовательно, своим приложением, поэтому оператор политики интерактивности библиотек является прекрасным примером.
- Это шаблон, если все мы следуем за ним
наши программы с большей вероятностью пройдут
Когда вы читаете ссылка Крокфорда вместе с ссылкой Croll (раздел прямого присваивания), о котором я упоминал в начале, вы понимаете, почему это выглядит сложнее, а не просто: sound.play = function() { ... }
- простота обслуживания, рефакторинг пространства имен и т.д. является только одной причиной.
Резюме
Вкратце:
- Могу ли я создавать глобальные переменные? Да, это просто, оставьте ключевое слово
var
перед объявлением. - Должен ли я создавать глобальные переменные? Вы должны использовать шаблон модуля, который неявно поддерживается node, и выражением
- Почему я создаю глобальные переменные? Если для конфигурации используется пространство имен конфигурации (например, Как сохранить настройки \w630 > .js установки/файлы конфигурации?)
Ответ 2
Вы можете:
global.name = function(){};
Но вам действительно следует избегать использования глобальных переменных, даже если их можно использовать.