2016-04-06 3 views
5

Я использую шаблон в моих модулях node.js, который кажется настолько очевидным для меня, что я предполагаю, что с ним что-то не так, или я увижу больше людей, которые это делают. Чтобы сохранить частные переменные, являющиеся глобальными для модуля, я просто добавляю их как свойства объекта модуля. Как так:использовать `module` как пространство имен

module.exports = { 

    init: function() { 
    module.someClient = initializeSomethingHere() 
    }, 

    someMethod: function(done) { 
    module.someClient.doSomething(done) 
    } 
} 

Это кажется предпочтительней для меня, чем-то вроде этого ...

var someClient; 

module.exports = { 
    init: function() { 
    someClient = initializeSomethingHere() 
    }, 

    someMethod: function(done) { 
    someClient.doSomething(done) 
    } 
} 

... потому что во втором примере вы должны пойти в поисках var someClient в верхней части файла чтобы исключить отсутствие ключевого слова var в рамках метода init. Я никогда не видел этот шаблон, используемый в других местах, поэтому я задаюсь вопросом, не хватает ли я чего-то, что делает его менее идеальным.

Мысли?

+0

Я использую оба варианта, в зависимости от того, что мне нужно. Если мне нужно экспортировать конструктор, вариант 2. Если мне нужен объект, который используется во многих разных местах, вариант 1. Ничего, ни «лучший». Помните, что узловые модули * кэшируются *, поэтому, если вы 'require()' этот код, опция 1 * может *, но не имеет * *, быть опасным, потому что это не является безопасным для модификации. Иногда это именно то, что вы хотите. Также посмотрите на код: вы экспортируете совершенно разные вещи (прототипированный конструктор объектов против объектного литерала), поэтому, если вам это нужно: отлично. –

ответ

4

Есть несколько возможных недостатков, которые приходят на ум.

1) Технически возможно, чтобы эти свойства были доступны и изменены вне модуля, но только если ссылка на сам модуль доступна вне его. Что-то, что делает модуль доступным через собственный экспорт (module.exports = module;, являющийся самым простым примером), предоставит их.

2) У вас может быть конфликт имен с встроенным свойством или будущим встроенным свойством, которое еще не существует (что может привести к разрыву кода в будущих версиях node.js). Это может быть очень проблематично и очень сложно отлаживать. В настоящее время встроенные свойства объекта модуля: children, exports, filename, id, loaded, paths, и parent.

потому что во втором примере вам нужно найти var someClient в верхней части файла, чтобы убедиться, что исключение ключевого слова var является преднамеренным в методе init.

Если это причина, вы можете просто использовать пространство имен, которое не является module. Например, добавив var private = {}; в начало каждого файла, а затем используя private.someClient вместо module.someClient.

Также 'use strict';, так что случайный ущерб var является ошибкой и не является случайным глобальным.

1

Недостатки

  • Вариант 1: Эта практика склонна к конфликту имен с встроено собственностью или будущей встроено собственностью, которая еще не существует, так как @paulpro заявил в своем ответе.

  • Вариант 2: Если вы пропустили ключевое слово var и выставите someClient по всему миру. Кроме того, вам нужно постоянно искать var someClient в верхней части файла.

Alternative

В JavaScript имеет функцию сферы, лучше определить все в пределах функции. Создание частных и открытых членов внутри функции.Ниже приведена схема проектирования, которая может быть следующей:

'use strict'; 

module.exports = (function(){ 

    //private 
    var someClient; 

    //public properties 
    var that={}; 

    that.init = function() { 
    someClient = initializeSomethingHere() 
    }, 

    that.someMethod: function(done) { 
    someClient.doSomething(done) 
    } 

    //expose only the required methods 
    return that; 
})(); 

Здесь представлены только открытые методы, которые прикреплены к этому объекту. И все остальные являются закрытыми для области функций. Даже если вы пропустили ключевое слово var в someClient, он не будет доступен вне функции, чего не произойдет, если вы используете 'use strict' наверху.

Логика первый раз, когда вам требуется файл xyz.js он возвращает that объект, а не функции.

Смежные вопросы