2015-05-06 4 views
4

Предположим, мы создаем простое приложение с узлами node.js и express (Note App). Мы хотим организовать наш код и поместить все контроллеры в отдельную папку. поэтому мы создаем папку и создаем в ней index.js. то мы добавим файлы js-контроллеров в эту папку. Затем инициализировать все контроллеры в главной точке входа index.js, а затем использовать require в server.js для доступа к нашим контроллерам. (Я не люблю большие, громоздкие и запутанные server.js файлы, вся логика втыкают в него!)Разный шаблон module.exports в node.js

Все эти пробы коды работают нормально, но я не могу понять разницу между этими кодовыми блоками.

1.

module.exports.init = function(app){ 
    console.log("notes controller init."); 
}; 

2.

function init(app){ 
    console.log("notes controller init."); 
}; 
module.exports.init = init; 

3.

(function (notesController){ 
    notesController.init = function(app){ 
     console.log("notes controller init."); 
    }; 
})(module.exports); 

4.

module.exports = { 
    init: function(app){ 
     console.log("notes controller init."); 
     } 
    } 

Есть ли разница в производительности или загрузке этих функций или что-то таинственное в JavaScript или просто разнообразие стиля кодирования?

Спасибо.

PS.

Я работаю back-end C# разработчиком, который ненавидел JavaScript! но я пытаюсь понять природу этого языка из-за Node.js. Я много говорю о модуле, об экспорте и прототипе и ... в JavaScript, но не могу найти ответ.

+0

Действительно, разница в производительности, но вы не можете измерить ее, поскольку она ничтожно мала. – zerkms

+0

@zerkms ведьма одна лучше? – Navid

+1

Вы ушли из 'module.exports = {init: function (app) {console.log (" note controller init. ");}}' – acbabis

ответ

3

Вариант №1 объявляет неименованную функцию и присваивает ее непосредственно module.exports.init.

Вариант № 2 создает локально с именем функции init, а затем присваивает, что module.exports.init. Что касается module.exports.init, разница между функциональными возможностями между # 1 и # 2 отсутствует. # 2 создал локальный символ init, который может быть использован для выполнения этой же функции локально как ярлык. Но результаты выполнения module.exports.init() будут одинаковыми с любым из четырех вариантов.

Вариант № 3 создает локальную область видимости функции IIFE, которая позволяет иметь отдельные переменные, которые ваша init функция может использовать, что бы выжить с одного вызова метода к другому, и даже быть частным в вашем модуле (другой части вашего модуля не могли даже получить к ним доступ). Вы не объявляете ни одну из этих частных переменных, но можете. Помимо этого, выполнение module.exports.init снова не будет отличаться от предыдущих двух параметров, поскольку для всех трех параметров назначается одна и та же функция ссылки module.exports.init.

Опция №4 определяет новый объект export.modules, а затем статически объявляет один метод в этом объекте. Это может быть полезным и компактным способом определения множества методов, которые все экспортируются (это общий шаблон проектирования), но я лично не буду использовать его, когда объявляю только один экспортированный метод, потому что опция №1 просто проще.

Любые различия в производительности между ними были бы только во время инициализации и, вероятно, настолько малы, что их было бы трудно измерить или найти в них материал.


Какой вариант лучше всего - это мнение. Я лично одобряю простейшее решение, которое следует за хорошей практикой кодирования и выполняет свою работу. Для меня это будет вариант №1, поскольку нет причин для определения init локально (опция № 2) и нет причин иметь IIFE для частных символов (опция № 3).

Итак, я бы предпочел не создавать именованную функцию, которая не используется или не нужна (опция № 2), и я бы предпочел не объявлять IIFE, который не используется для каких-либо целей (опция № 3) ,

Как правило, я использую опцию # 4, если я объявляю несколько экспортированных методов, потому что это самый компактный синтаксис для этого.

+0

Не только IEFE, который не используется в этом примере, но особенно кажется излишним, если учесть, что каждый модуль уже имеет свой собственный модуль. – Bergi

+1

@ Bergi - yep IIFE предлагает конфиденциальность от других частей вашего собственного модуля, поскольку конфиденциальность уже существует из внешнего мира через область функций модуля. – jfriend00

+0

@Navid - Добавлены комментарии к недавно добавленной опции # 4. – jfriend00