CommonJS 模块模式
CommonJS module pattern
我从
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.
})
});
上面写着
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.
粗体部分我不清楚。 js 解释器如何知道所有这些代码都在模块闭包内而不是在全局范围内?
模块闭包从哪里开始,从哪里结束?
据我所知
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.
有什么解释吗?
您实际上漏掉了您引用的摘录中的最后一行:
module.exports = TodoStore;
CommonJS 是一个 API 来定义使用以下约定的模块:
- 每个文件定义一个模块,并在隔离环境中执行;也就是说它定义的变量在模块外不可用。
- 为了允许导入其他模块,模块可以使用全局变量
require
,允许它导入其他模块
- 以同样的方式,变量
module
可用于模块,以便它可以设置其 exports
属性来定义模块应导出的内容;您在模块 a.js 中为 module.exports
设置的值正是 require('./a')
将 return.
每个实现 CommonJS 的 JS 环境都必须知道这些规则。当然,这包括 Node.js,但也包括 Browserify 和 Webpack 等捆绑器,它们将打包您的代码,以便遵守这些约定。
这样,您可以控制导出模块的哪一部分。
P.S。 : 请注意,您还可以使用 exports
var 来定义您的导出,并且它的使用与 module.exports
略有不同。详情见this Whosebug question and answer
常见的 JS 模式使用构造函数来定义您的实用程序。
定义为class。
var moduleName = function() {
// private variables
// public functions
this.method1 = function() {
// logic1 goes here
};
this.method2 = function() {
// logic2 goes here
};
};
所以我们要使用
将class导出到其他模块
module.exports = moduleName;
以便其他模块可以导入它、实例化它然后使用该功能。
如何使用?
var module = require('moduleName'); //importing the module created above
此处获取、执行模块定义,然后在 'module' 变量中可用。
这个变量名可以是任何东西
var objectOfModule = new module(); //instance is created
objectOfModule .method1(); //use1
console.log(objectOfModule .method2()); //use2
谢谢。
我从
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.
})
});
上面写着
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.
粗体部分我不清楚。 js 解释器如何知道所有这些代码都在模块闭包内而不是在全局范围内? 模块闭包从哪里开始,从哪里结束?
据我所知
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.
有什么解释吗?
您实际上漏掉了您引用的摘录中的最后一行:
module.exports = TodoStore;
CommonJS 是一个 API 来定义使用以下约定的模块:
- 每个文件定义一个模块,并在隔离环境中执行;也就是说它定义的变量在模块外不可用。
- 为了允许导入其他模块,模块可以使用全局变量
require
,允许它导入其他模块 - 以同样的方式,变量
module
可用于模块,以便它可以设置其exports
属性来定义模块应导出的内容;您在模块 a.js 中为module.exports
设置的值正是require('./a')
将 return.
每个实现 CommonJS 的 JS 环境都必须知道这些规则。当然,这包括 Node.js,但也包括 Browserify 和 Webpack 等捆绑器,它们将打包您的代码,以便遵守这些约定。
这样,您可以控制导出模块的哪一部分。
P.S。 : 请注意,您还可以使用 exports
var 来定义您的导出,并且它的使用与 module.exports
略有不同。详情见this Whosebug question and answer
常见的 JS 模式使用构造函数来定义您的实用程序。
定义为class。
var moduleName = function() {
// private variables
// public functions
this.method1 = function() {
// logic1 goes here
};
this.method2 = function() {
// logic2 goes here
};
};
所以我们要使用
将class导出到其他模块 module.exports = moduleName;
以便其他模块可以导入它、实例化它然后使用该功能。
如何使用?
var module = require('moduleName'); //importing the module created above
此处获取、执行模块定义,然后在 'module' 变量中可用。
这个变量名可以是任何东西
var objectOfModule = new module(); //instance is created
objectOfModule .method1(); //use1
console.log(objectOfModule .method2()); //use2
谢谢。