Если переменная javascript находится вне класса, но внутри закрытия модуля, является ли она частной?

Я наткнулся на следующий код из https://facebook.github.io/flux/docs/todo-list.html#content, и у меня возник этот вопрос, поскольку веб-сайт заявляет, что

Этот объект (_todos) содержит все отдельные задачи. Поскольку эта переменная находится вне класса, но внутри замыкания модуля, она остается приватной — ее нельзя изменить напрямую извне модуля.

Это правда? Насколько мне известно, кажется, что _todos является глобальным объектом.

var AppDispatcher = require('../dispatcher/AppDispatcher');
var EventEmitter = require('events').EventEmitter;
var TodoConstants = require('../constants/TodoConstants');
var assign = require('object-assign');

var CHANGE_EVENT = 'change';

var _todos = {}; // collection of todo items

/**
 * Create a TODO item.
 * @param {string} text The content of the TODO
 */
function create(text) {
  // Using the current timestamp in place of a real id.
  var id = Date.now();
  _todos[id] = {
    id: id,
    complete: false,
    text: text
  };
}

/**
 * Delete a TODO item.
 * @param {string} id
 */
function destroy(id) {
  delete _todos[id];
}

var TodoStore = assign({}, EventEmitter.prototype, {

  /**
   * Get the entire collection of TODOs.
   * @return {object}
   */
  getAll: function() {
    return _todos;
  },

  emitChange: function() {
    this.emit(CHANGE_EVENT);
  },

  /**
   * @param {function} callback
   */
  addChangeListener: function(callback) {
    this.on(CHANGE_EVENT, callback);
  },

  /**
   * @param {function} callback
   */
  removeChangeListener: function(callback) {
    this.removeListener(CHANGE_EVENT, callback);
  },

      dispatcherIndex: AppDispatcher.register(function(payload) {
        var action = payload.action;
        var text;

        switch(action.actionType) {
          case TodoConstants.TODO_CREATE:
            text = action.text.trim();
            if (text !== '') {
              create(text);
              TodoStore.emitChange();
            }
            break;

          case TodoConstants.TODO_DESTROY:
            destroy(action.id);
            TodoStore.emitChange();
            break;

          // add more cases for other actionTypes, like TODO_UPDATE, etc.
        }

        return true; // No errors. Needed by promise in Dispatcher.
      })

})    ;

module.exports = TodoStore;

person Bob    schedule 30.08.2015    source источник


Ответы (1)


Да, это правда.

В вашем примере _todos относится к самому модулю (то есть к файлу) и НЕ является глобальным.

В node.js переменные привязаны к модулю. И он не станет глобальным (как в браузере). Для справки см. этот вопрос.

Если вы используете что-то вроде browserify, это по-прежнему верно, потому что с точки зрения верхнего уровня browserify использует немедленно вызываемое функциональное выражение для загрузки в отображении зависимостей (т.е. модулей), которые в основном заключены в функцию, имеющую свою собственную область (НЕ глобальную область). Дополнительную информацию о том, как это работает, можно найти здесь.

person danillouz    schedule 30.08.2015
comment
Я понимаю. Так что это верно только тогда, когда я загружаю этот файл как модуль в браузере, и если я загружаю этот файл обычным способом (в теге скрипта), _todos станет глобальной переменной, верно? - person Bob; 30.08.2015
comment
Да, строго говоря, в среде браузера и невозможности облегчения модулей CommonJS (например, в node.js или с помощью чего-то вроде браузера) _todos будет глобальным (если он определен в глобальной области). - person danillouz; 30.08.2015