在Node.js中对模块载入和执行进行了包装,使得模块文件中的变量在一个闭包中,不会污染全局变量,和他人冲突。
前端模块通常是我们开发人员为了避免和他人冲突才把模块代码放置在一个闭包中。
如何封装Node.js和前端通用的模块,我们可以参考Underscore.js 实现,他就是一个Node.js和前端通用的功能函数模块,查看代码:
// Create a safe reference to the Underscore object for use below.
var _ = function(obj) {
if (obj instanceof _) return obj;
if (!(this instanceof _)) return new _(obj);
this._wrapped = obj;
};
// Export the Underscore object for **Node.js**, with
// backwards-compatibility for the old `require()` API. If we’re in
// the browser, add `_` as a global object via a string identifier,
// for Closure Compiler “advanced” mode.
if (typeof exports !== ‘undefined’) {
if (typeof module !== ‘undefined’ && module.exports) {
exports = module.exports = _;
}
exports._ = _;
} else {
root._ = _;
}
通过判断exports是否存在来决定将局部变量 _ 赋值给exports,向后兼容旧的require() API,如果在浏览器中,通过一个字符串标识符“_”作为一个全局对象;完整的闭包如下:
(function() {
// Baseline setup
// ————–
// Establish the root object, `window` in the browser, or `exports` on the server.
var root = this;
// Create a safe reference to the Underscore object for use below.
var _ = function(obj) {
if (obj instanceof _) return obj;
if (!(this instanceof _)) return new _(obj);
this._wrapped = obj;
};
// Export the Underscore object for **Node.js**, with
// backwards-compatibility for the old `require()` API. If we’re in
// the browser, add `_` as a global object via a string identifier,
// for Closure Compiler “advanced” mode.
if (typeof exports !== ‘undefined’) {
if (typeof module !== ‘undefined’ && module.exports) {
exports = module.exports = _;
}
exports._ = _;
} else {
root._ = _;
}
}).call(this);
通过function定义构建了一个闭包,call(this)是将function在this对象下调用,以避免内部变量污染到全局作用域。浏览器中,this指向的是全局对象(window对象),将“_”变量赋在全局对象上“root._”,以供外部调用。









