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

在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){}

时间: 2024-10-28 12:49:13

Node.js中对通用模块的封装方法_node.js的相关文章

快速掌握Node.js中setTimeout和setInterval的使用方法_node.js

Node.js和js一样也有计时器,超时计时器.间隔计时器.及时计时器,它们以及process.nextTick(callback)函数来实现事件调度.今天先学下setTimeout和setInterval的使用. 一.setTimeout超时计时器(和GCD中的after类似) 在node.js中可以使用node.js内置的setTimeout(callback,delayMillSeconds,[args])方法.当调用setTime()时回调函数会在delayMillSeconds后 执行

Node.js中路径处理模块path详解_node.js

前言 在node.js中,提供了一个path某块,在这个模块中,提供了许多使用的,可被用来处理与转换路径的方法与属性,将path的接口按照用途归类,仔细琢磨琢磨,也就没那么费解了.下面我们就来详细介绍下关于Node.js中的路径处理模块path. 获取路径/文件名/扩展名      获取路径:path.dirname(filepath)      获取文件名:path.basename(filepath)      获取扩展名:path.extname(filepath) 获取所在路径 例子如下

详解js中class的多种函数封装方法_javascript技巧

本文实例讲解了js中class的多种函数封装方法,分享给大家供大家参考,具体内容如下 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>关于class的多种函数封装</title> <style> body{ margin: 0; } li{ height: 20px; } </style

解析Node.js异常处理中domain模块的使用方法_node.js

NodeJS 提供了 domain 模块,可以简化异步代码的异常处理.在介绍该模块之前,我们需要首先理解"域"的概念.简单的讲,一个域就是一个 JS 运行环境,在一个运行环境中,如果一个异常没有被捕获,将作为一个全局异常被抛出.NodeJS 通过 process 对象提供了捕获全局异常的方法,示例代码如下 process.on('uncaughtException', function (err) { console.log('Error: %s', err.message); });

Node.js重新刷新session过期时间的方法_node.js

在Node.js中,我们通常使用express-session这个包来使用和管理session,保存服务端和客户端浏览器之间的会话状态.那如何才能实现当用户刷新当前页面或者点击页面上的按钮时重新刷新session的过期时间呢?类似于ASP.NET中session会话状态,只要在一定的时间内页面一直保持活动状态,session就不会过期.通过下面的代码可以实现这个功能,我们在Node.js的代码中加入下面的中间件: // use this middleware to reset cookie ex

Node.js批量给图片加水印的方法_node.js

一.准备工作: 首先,你要阅读完这篇文章:http://www.jb51.net/article/97391.htm. 然后,我们安装node.js的一个模块:imageinfo. npm install imageinfo 二.直接上DEMO: 步骤如下: step1:文件夹结构 step2:JS代码 //引用文件系统模块 var fs = require("fs"); //引用imageinfo模块 var imageInfo = require("imageinfo&q

Node.js中JavaScript操作MySQL的常用方法整理_node.js

一.建立数据库连接:createConnection(Object)方法      该方法接受一个对象作为参数,该对象有四个常用的属性host,user,password,database.与php中链接数据库的参数相同.属性列表如下: host: 连接数据库所在的主机名. (默认: localhost)  port: 连接端口. (默认: 3306)  localAddress: 用于TCP连接的IP地址. (可选)  socketPath: 链接到unix域的路径.在使用host和port时

在Node.js应用中读写Redis数据库的简单方法_node.js

 在开始本文之前请确保安装好 Redis 和 Node.js 以及 Node.js 的 Redis 扩展 -- node_redis 首先创建一个新文件夹并新建文本文件 app.js 文件内容如下:   var redis = require("redis") , client = redis.createClient(); client.on("error", function (err) { console.log("Error " + er

node.js中的socket.io的广播消息_node.js

在多个客户端与服务器端建立连接后,socket.io()服务器具有一个sockets属性,属性值为所有与客户端建立连接的socket对象.可以利用该对象的send方法或emit方法向所有客户端广播消息. io.sockets.send("user commected); io.socket.emit("login",names); 案例 server.js代码: 复制代码 代码如下: var express=require("express"); var