admin管理员组

文章数量:1023204

I have taken this from

Flux architecture

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,
    plete: 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.
  })

});

where it says

There are a few important things to note in the above code. To start, we are maintaining a private data structure called _todos. This object contains all the individual to-do items. Because this variable lives outside the class, but within the closure of the module, it remains private — it cannot be directly changed from outside of the module. This helps us preserve a distinct input/output interface for the flow of data by making it impossible to update the store without using an action.

The bold part is unclear to me. How can js interpreter know that all those code is inside a module closure and not in the globals scope? From where the module closure start and where ends?

As far as I know

The scope of a variable declared with var is its current execution context, which is either the enclosing function or, for variables declared outside any function, global.

Any explanation?

I have taken this from

Flux architecture

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,
    plete: 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.
  })

});

where it says

There are a few important things to note in the above code. To start, we are maintaining a private data structure called _todos. This object contains all the individual to-do items. Because this variable lives outside the class, but within the closure of the module, it remains private — it cannot be directly changed from outside of the module. This helps us preserve a distinct input/output interface for the flow of data by making it impossible to update the store without using an action.

The bold part is unclear to me. How can js interpreter know that all those code is inside a module closure and not in the globals scope? From where the module closure start and where ends?

As far as I know

The scope of a variable declared with var is its current execution context, which is either the enclosing function or, for variables declared outside any function, global.

Any explanation?

Share Improve this question edited Feb 11, 2016 at 15:18 Herrington Darkholme 6,3251 gold badge30 silver badges45 bronze badges asked Feb 11, 2016 at 14:33 NemusNemus 1,4823 gold badges28 silver badges54 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 5

You're actually missing the last line from the extract you quoted :

module.exports = TodoStore;

CommonJS is an API to define modules that use the following conventions :

  • Every file defines a module and is executed in an isolated environment ; that is to say that the variables it defines won't be available from outside the module.
  • To allow importing other modules, a global variable require is made available to the module, allowing it to import other modules
  • In the same way, the variable module is made available to the module so that it can set its exports attribute to define what should be exported by your module ; the value you set for module.exports in your module a.js is exactly what require('./a') will return.

Every JS environment that implements CommonJS has to know these rules. That includes Node.js, of course, but also bundlers like Browserify and Webpack that will package your codes so that these conventions are respected.

This way, you can control which part of your module will be exported.

P.S. : note that you can also use the exports var to define your exports, and that its use is slightly different from module.exports. See this StackOverflow question and answer for details

Common JS pattern uses the constructor function to define your utilities.

It is defined in the form of class.

var moduleName = function() {

  // private variables

  // public functions
  this.method1 = function() {
    // logic1 goes here
  };

  this.method2 = function() {
    // logic2 goes here
  };

};

So we are going to export the class to other modules using

    module.exports = moduleName;

So that other modules can import it, instantiate it and then use the functionality.

How to use it?

    var module = require('moduleName');  //importing the module created above

Here the module definition is fetched,executed and then available in 'module' variable.

This variable name can be anything

    var objectOfModule = new module(); //instance is created

    objectOfModule .method1(); //use1

    console.log(objectOfModule .method2()); //use2

Thanks.

I have taken this from

Flux architecture

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,
    plete: 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.
  })

});

where it says

There are a few important things to note in the above code. To start, we are maintaining a private data structure called _todos. This object contains all the individual to-do items. Because this variable lives outside the class, but within the closure of the module, it remains private — it cannot be directly changed from outside of the module. This helps us preserve a distinct input/output interface for the flow of data by making it impossible to update the store without using an action.

The bold part is unclear to me. How can js interpreter know that all those code is inside a module closure and not in the globals scope? From where the module closure start and where ends?

As far as I know

The scope of a variable declared with var is its current execution context, which is either the enclosing function or, for variables declared outside any function, global.

Any explanation?

I have taken this from

Flux architecture

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,
    plete: 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.
  })

});

where it says

There are a few important things to note in the above code. To start, we are maintaining a private data structure called _todos. This object contains all the individual to-do items. Because this variable lives outside the class, but within the closure of the module, it remains private — it cannot be directly changed from outside of the module. This helps us preserve a distinct input/output interface for the flow of data by making it impossible to update the store without using an action.

The bold part is unclear to me. How can js interpreter know that all those code is inside a module closure and not in the globals scope? From where the module closure start and where ends?

As far as I know

The scope of a variable declared with var is its current execution context, which is either the enclosing function or, for variables declared outside any function, global.

Any explanation?

Share Improve this question edited Feb 11, 2016 at 15:18 Herrington Darkholme 6,3251 gold badge30 silver badges45 bronze badges asked Feb 11, 2016 at 14:33 NemusNemus 1,4823 gold badges28 silver badges54 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 5

You're actually missing the last line from the extract you quoted :

module.exports = TodoStore;

CommonJS is an API to define modules that use the following conventions :

  • Every file defines a module and is executed in an isolated environment ; that is to say that the variables it defines won't be available from outside the module.
  • To allow importing other modules, a global variable require is made available to the module, allowing it to import other modules
  • In the same way, the variable module is made available to the module so that it can set its exports attribute to define what should be exported by your module ; the value you set for module.exports in your module a.js is exactly what require('./a') will return.

Every JS environment that implements CommonJS has to know these rules. That includes Node.js, of course, but also bundlers like Browserify and Webpack that will package your codes so that these conventions are respected.

This way, you can control which part of your module will be exported.

P.S. : note that you can also use the exports var to define your exports, and that its use is slightly different from module.exports. See this StackOverflow question and answer for details

Common JS pattern uses the constructor function to define your utilities.

It is defined in the form of class.

var moduleName = function() {

  // private variables

  // public functions
  this.method1 = function() {
    // logic1 goes here
  };

  this.method2 = function() {
    // logic2 goes here
  };

};

So we are going to export the class to other modules using

    module.exports = moduleName;

So that other modules can import it, instantiate it and then use the functionality.

How to use it?

    var module = require('moduleName');  //importing the module created above

Here the module definition is fetched,executed and then available in 'module' variable.

This variable name can be anything

    var objectOfModule = new module(); //instance is created

    objectOfModule .method1(); //use1

    console.log(objectOfModule .method2()); //use2

Thanks.

本文标签: javascriptCommonJS module patternStack Overflow