【问题标题】:If a javascript variable lives outside the class, but within the closure of the module, is it private?如果一个 javascript 变量存在于类之外,但在模块的闭包内,它是私有的吗?
【发布时间】:2015-11-24 15:04:31
【问题描述】:

我从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;

【问题讨论】:

    标签: javascript global-variables closures private flux


    【解决方案1】:

    是的,这是真的。

    在您的示例中,_todos 的范围仅限于模块(即文件)本身,而不是全局的。

    在 node.js 中,变量的范围是模块。而且它不会成为一个全局的(就像在浏览器上一样)。参考见this question

    如果你使用像browserify 这样的东西,这仍然是正确的,因为从顶层的角度来看,browserify 使用立即调用的函数表达式来加载依赖项(即模块)的映射,这些依赖项基本上包装在一个拥有它自己的函数中范围(不是全局范围)。有关其工作原理的更多信息,请访问here

    【讨论】:

    • 我明白了。所以只有当我将这个文件作为一个模块加载到浏览器中时,如果我以正常方式(在脚本标签中)加载这个文件,_todos 将成为一个全局变量,对吗?
    • 是的,严格来说,当在浏览器环境中并且无法促进 CommonJS 模块(如在 node.js 中或通过类似 browserify 的方式)时,_todos 将是一个全局的(如果已定义在全球范围内)。
    猜你喜欢
    • 1970-01-01
    • 2013-04-01
    • 2014-09-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-28
    相关资源
    最近更新 更多