Подтвердить что ты не робот

Глобальная функция в express.js?

Как определить глобальную функцию в express.js, без require я могу назвать ее

4b9b3361

Ответ 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(){};

Но вам действительно следует избегать использования глобальных переменных, даже если их можно использовать.