最新文章专题视频专题问答1问答10问答100问答1000问答2000关键字专题1关键字专题50关键字专题500关键字专题1500TAG最新视频文章推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37视频文章20视频文章30视频文章40视频文章50视频文章60 视频文章70视频文章80视频文章90视频文章100视频文章120视频文章140 视频2关键字专题关键字专题tag2tag3文章专题文章专题2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章专题3
当前位置: 首页 - 科技 - 知识百科 - 正文

Node.js中对通用模块的封装方法

来源:动视网 责编:小采 时间:2020-11-27 20:27:52
文档

Node.js中对通用模块的封装方法

Node.js中对通用模块的封装方法:在Node.js中对模块载入和执行进行了包装,使得模块文件中的变量在一个闭包中,不会污染全局变量,和他人冲突。前端模块通常是我们开发人员为了避免和他人冲突才把模块代码放置在一个闭包中。如何封装Node.js和前端通用的模块,我们可以参考Underscore
推荐度:
导读Node.js中对通用模块的封装方法:在Node.js中对模块载入和执行进行了包装,使得模块文件中的变量在一个闭包中,不会污染全局变量,和他人冲突。前端模块通常是我们开发人员为了避免和他人冲突才把模块代码放置在一个闭包中。如何封装Node.js和前端通用的模块,我们可以参考Underscore


在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._”,以供外部调用。

和Underscore.js 类似的Lo-Dash,也是使用了类似的方案,只是兼容了AMD模块载入的兼容:

;(function() {

 /** Used as a safe reference for `undefined` in pre ES5 environments */
 var undefined;
 /** Used to determine if values are of the language type Object */
 var objectTypes = {
 'boolean': false,
 'function': true,
 'object': true,
 'number': false,
 'string': false,
 'undefined': false
 };
 /** Used as a reference to the global object */
 var root = (objectTypes[typeof window] && window) || this;

 /** Detect free variable `exports` */
 var freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports;

 /** Detect free variable `module` */
 var freeModule = objectTypes[typeof module] && module && !module.nodeType && module;

 /** Detect the popular CommonJS extension `module.exports` */
 var moduleExports = freeModule && freeModule.exports === freeExports && freeExports;

/*--------------------------------------------------------------------------*/

 // expose Lo-Dash
 var _ = runInContext();

 // some AMD build optimizers, like r.js, check for condition patterns like the following:
 if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) {
 // Expose Lo-Dash to the global object even when an AMD loader is present in
 // case Lo-Dash was injected by a third-party script and not intended to be
 // loaded as a module. The global assignment can be reverted in the Lo-Dash
 // module by its `noConflict()` method.
 root._ = _;

 // define as an anonymous module so, through path mapping, it can be
 // referenced as the "underscore" module
 define(function() {
 return _;
 });
 }
 // check for `exports` after `define` in case a build optimizer adds an `exports` object
 else if (freeExports && freeModule) {
 // in Node.js or RingoJS
 if (moduleExports) {
 (freeModule.exports = _)._ = _;
 }
 // in Narwhal or Rhino -require
 else {
 freeExports._ = _;
 }
 }
 else {
 // in a browser or Rhino
 root._ = _;
 }
}.call(this));

再来看看Moment.js的封装闭包主要代码:

(function (undefined) {
 var moment;
 // check for nodeJS
 var hasModule = (typeof module !== 'undefined' && module.exports);
/************************************
 Exposing Moment
 ************************************/

 function makeGlobal(deprecate) {
 var warned = false, local_moment = moment;
 /*global ender:false */
 if (typeof ender !== 'undefined') {
 return;
 }
 // here, `this` means `window` in the browser, or `global` on the server
 // add `moment` as a global object via a string identifier,
 // for Closure Compiler "advanced" mode
 if (deprecate) {
 this.moment = function () {
 if (!warned && console && console.warn) {
 warned = true;
 console.warn(
 "Accessing Moment through the global scope is " +
 "deprecated, and will be removed in an upcoming " +
 "release.");
 }
 return local_moment.apply(null, arguments);
 };
 } else {
 this['moment'] = moment;
 }
 }

 // CommonJS module is defined
 if (hasModule) {
 module.exports = moment;
 makeGlobal(true);
 } else if (typeof define === "function" && define.amd) {
 define("moment", function (require, exports, module) {
 if (module.config().noGlobal !== true) {
 // If user provided noGlobal, he is aware of global
 makeGlobal(module.config().noGlobal === undefined);
 }

 return moment;
 });
 } else {
 makeGlobal();
 }
}).call(this);

从上面的几个例子可以看出,在封装Node.js和前端通用的模块时,可以使用以下逻辑:

if (typeof exports !== "undefined") {
 exports.** = **;
} else {
 this.** = **;
}

即,如果exports对象存在,则将局部变量装载在exports对象上,如果不存在,则装载在全局对象上。如果加上ADM规范的兼容性,那么多加一句判断:

if (typeof define === "function" && define.amd){}

更多Node.js中对通用模块的封装方法相关文章请关注PHP中文网!

文档

Node.js中对通用模块的封装方法

Node.js中对通用模块的封装方法:在Node.js中对模块载入和执行进行了包装,使得模块文件中的变量在一个闭包中,不会污染全局变量,和他人冲突。前端模块通常是我们开发人员为了避免和他人冲突才把模块代码放置在一个闭包中。如何封装Node.js和前端通用的模块,我们可以参考Underscore
推荐度:
  • 热门焦点

最新推荐

猜你喜欢

热门推荐

专题
Top