深入理解node.js的module.export 和 export方法的区别

你肯定非常熟悉nodejs模块中的exports对象,你可以用它创建你的模块。例如:(假设这是rocker.js文件)

exports.name = function() {
    console.log(‘My name is Lemmy Kilmister‘);
};

在另一个文件中你这样引用

var rocker = require(‘./rocker.js‘);
rocker.name(); // ‘My name is Lemmy Kilmister‘

那到底Module.exports是什么呢?它是否合法呢?

其实,Module.exports才是真正的接口,exports只不过是它的一个辅助工具。 最终返回给调用的是Module.exports而不是exports。

所有的exports收集到的属性和方法,都赋值给了Module.exports。当然,这有个前提,就是Module.exports本身不具备任何属性和方法。如果,Module.exports已经具备一些属性和方法,那么exports收集来的信息将被忽略。

修改rocker.js如下:

module.exports = ‘ROCK IT!‘;
exports.name = function() {
    console.log(‘My name is Lemmy Kilmister‘);
};

再次引用执行rocker.js

var rocker = require(‘./rocker.js‘);
rocker.name(); // TypeError: Object ROCK IT! has no method ‘name‘

发现报错:对象“ROCK IT!”没有name方法

rocker模块忽略了exports收集的name方法,返回了一个字符串“ROCK IT!”。由此可知,你的模块并不一定非得返回“实例化对象”。你的模块可以是任何合法的javascript对象--boolean, number, date, JSON, string, function, array等等。

你的模块可以是任何你设置给它的东西。如果你没有显式的给Module.exports设置任何属性和方法,那么你的模块就是exports设置给Module.exports的属性。

下面例子中,你的模块是一个类:

module.exports = function(name, age) {
    this.name = name;
    this.age = age;
    this.about = function() {
        console.log(this.name +‘ is ‘+ this.age +‘ years old‘);
    };
};

可以这样应用它:

var Rocker = require(‘./rocker.js‘);
var r = new Rocker(‘Ozzy‘, 62);
r.about(); // Ozzy is 62 years old

下面例子中,你的模块是一个数组:

module.exports = [‘Lemmy Kilmister‘, ‘Ozzy Osbourne‘, ‘Ronnie James Dio‘, ‘Steven Tyler‘, ‘Mick Jagger‘];

可以这样应用它:

var rocker = require(‘./rocker.js‘);
console.log(‘Rockin in heaven: ‘ + rocker[2]); //Rockin in heaven: Ronnie James Dio

现在你明白了,如果你想你的模块是一个特定的类型就用Module.exports。如果你想的模块是一个典型的“实例化对象”就用exports

给Module.exports添加属性类似于给exports添加属性。例如:

module.exports.name = function() {
    console.log(‘My name is Lemmy Kilmister‘);
};

同样,exports是这样的

exports.name = function() {
    console.log(‘My name is Lemmy Kilmister‘);
};

请注意,这两种结果并不想同。前面已经提到module.exports是真正的接口,exports只不过是它的辅助工具。推荐使用exports导出,除非你打算从原来的“实例化对象”改变成一个类型

API文档是枯燥的,下面本人收集了一些论坛经常有人疑问和开源代码中经常遇到的案例供大家研究一下。

文章博客地址 排版更佳。。

##module.exports与exports的区别

每一个node.js执行文件,都自动创建一个module对象,同时,module对象会创建一个叫exports的属性,初始化的值是 {}

 module.exports = {};

Node.js为了方便地导出功能函数,node.js会自动地实现以下这个语句

foo.js

 exports.a = function(){
 console.log(‘a‘)
 }

 exports.a = 1

test.js

 var x = require(‘./foo‘);

 console.log(x.a)

看到这里,相信大家都看到答案了,exports是引用 module.exports的值。module.exports 被改变的时候,exports不会被改变,而模块导出的时候,真正导出的执行是module.exports,而不是exports

再看看下面例子

foo.js

 exports.a = function(){
  console.log(‘a‘)
 }

 module.exports = {a: 2}
 exports.a = 1

test.js

 var x = require(‘./foo‘);

 console.log(x.a)

result:

 2

exports在module.exports 被改变后,失效。

是不是开始有点廓然开朗,下面将会列出开源模块中,经常看到的几个使用方式。

##module.exports = View

function View(name, options) {
   options = options || {};
   this.name = name;
   this.root = options.root;
   var engines = options.engines;
   this.defaultEngine = options.defaultEngine;
   var ext = this.ext = extname(name);
   if (!ext && !this.defaultEngine) throw new Error(‘No default engine was specified and no         extension was provided.‘);
   if (!ext) name += (ext = this.ext = (‘.‘ != this.defaultEngine[0] ? ‘.‘ : ‘‘) +     this.defaultEngine);
   this.engine = engines[ext] || (engines[ext] = require(ext.slice(1)).__express);
   this.path = this.lookup(name);
 }

 module.exports = View;

javascript里面有一句话,函数即对象,View 是对象,module.export =View, 即相当于导出整个view对象。外面模块调用它的时候,能够调用View的所有方法。不过需要注意,只有是View的静态方法的时候,才能够被调用,prototype创建的方法,则属于View的私有方法。

foo.js

 function View(){

 }

 View.prototype.test = function(){
  console.log(‘test‘)
 }

 View.test1 = function(){
  console.log(‘test1‘)
 }

module.exports = View

test.js

 var x = require(‘./foo‘);

 console.log(x) //{ [Function: View] test1: [Function] }
 console.log(x.test) //undefined
 console.log(x.test1) //[Function]
 x.test1() //test1

##var app = exports = module.exports = {};

其实,当我们了解到原理后,不难明白这样的写法有点冗余,其实是为了保证,模块的初始化环境是干净的。同时也方便我们,即使改变了 module.exports 指向的对象后,依然能沿用 exports的特性

 exports = module.exports = createApplication;

 /**
  * Expose mime.
  */

 exports.mime = connect.mime;

例子,当中module.exports = createApplication改变了module.exports了,让exports失效,通过exports = module.exports的方法,让其恢复原来的特点。

##exports.init= function(){}

这种最简单,直接就是导出模块 init的方法。

##var mongoose = module.exports = exports = new Mongoose;

集多功能一身,不过根据上文所描述的,大家应该不能得出答案。

时间: 2024-10-07 19:29:31

深入理解node.js的module.export 和 export方法的区别的相关文章

方便大家学习的Node.js教程(一):理解Node.js

理解Node.js 为了理解Node.js是如何工作的,首先你需要理解一些使得Javascript适用于服务器端开发的关键特性.Javascript是一门简单而又灵活的语言,这种灵活性让它能够经受住时间的考验.函数.闭包等特性使Javascript成为一门适合Web开发的理想语言. 有一种偏见认为Javascript是不可靠的,然而事实并非如此.人们对Javascript的偏见来源于DOM,DOM是浏览器厂商提供的用于Javascript与浏览器交互的API,不同浏览器厂商实现的DOM存在差异.

理解Node.js的事件轮询

前言 总括 : 原文地址:理解Node.js的事件轮询 Node小应用:Node-sample 智者阅读群书.亦阅历人生 正文 Node.js的两个基本概念 Node.js的第一个基本概念就是I/O操作开销是巨大的: 所以,当前变成技术中最大的浪费来自于等待I/O操作的完毕.有几种方法能够解决性能的影响: 同步方式:按次序一个一个的处理请求.利:简单.弊:不论什么一个请求都能够堵塞其它全部请求. 开启新进程:每一个请求都开启一个新进程.利:简单:弊:大量的链接意味着大量的进程. 开启新线程:每一

JS截取字符串substr 和 substring方法的区别

substr 方法 返回一个从指定位置开始的指定长度的子字符串. stringvar.substr(start [, length ]) 参数 stringvar 必选项.要提取子字符串的字符串文字或 String 对象. start 必选项.所需的子字符串的起始位置.字符串中的第一个字符的索引为 0. length 可选项.在返回的子字符串中应包括的字符个数. 说明 如果 length 为 0 或负数,将返回一个空字符串.如果没有指定该参数,则子字符串将延续到 stringvar 的最后. 示

node.js中module.export与export的区别。

对module.exports和exports的一些理解 可能是有史以来最简单通俗易懂的有关Module.exports和exports区别的文章了. exports = module.exports = {}; 所以module.exports和exports的区别就是var a={}; var b=a;,a和b的区别 看起来木有什么太大区别,但实际用起来的时候却又有区别,这是为啥呢,请听我细细道来 关于Module.exports和exports有什么区别,网上一搜一大把,但是说的都太复杂了

Node.js 的module 系统

相较于原生的JavaScript,不同的JavaScript文件之间很难共享变量.有鉴于此,Node.js在JavaScript的基础上进行了扩充,引入了require,exports,module三个global object. 一.absolute module 和 relative module Smashing Node.js 的作者将node.js 中的modules 分成了两类,一类是absolute modules,一类是 relative modules. <1> absolu

浅理解node.js

最近开始了解node.js,在这里把最近看的(七天学会nodejs)大概串一下,加深一下理解. node.js是一个解析器——一种运行环境,允许JS使用运行环境提供的内置对象和方法做一些事情.例如fs/http内置对象. ——运行在服务端的JavaScript 1 先来个实际点的小例子,感受一下nodejs var http = require('http'); http.createServer(function (request, response) { response.writeHead

【译】理解node.js事件轮询

Node.js的第一个基本论点是I/O开销很大. 当前编程技术中等待I/O完成会浪费大量的时间.有几种方法可以处理这种性能上的影响: 同步:每次处理一个请求,依次处理.优点:简单:缺点:任何一个请求都可以阻塞所有其他的请求. Fork一个新进程:开一个新进程来处理每个请求.优点:容易:缺点:不能很好的扩展,成百上千个连接意味着成百上千个进程.fork()函数相当于Unix程序员的锤子,因为它很有用,每个问题看起来就像一个钉子,通常会被过度使用.(译者注:直译比较拗口,我理解的意思是,Unix程序

理解Node.js安装及模块化

1.安装Node Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境. Node.js 使用了一个事件驱动.非阻塞式 I/O 的模型,使其轻量又高效. Node.js 的包管理器 npm(Node Package Manage),是全球最大的开源库生态系统. 中文网:http://nodejs.cn/英文网:https://nodejs.org 2.REPL(交互式解释器) REPL(Read Eval Print Loop:交互式解释器),表示一个电脑的环境

理解Node.js(译文)

正文 当我向别人介绍Node.js 的时候一般会有两种反应,要么是立马就弄明白它是个什么玩意儿,要么是被它搞的很糊涂. 如果你现在还处于后者,下面就是我对于node的解释: 它是一个命令行工具,你可以下载一个tarball文件,编译然后安装源文件: 它可以让你在你的终端输入node my_app.js来运行Javascript程序: Node的JS代码是由 V8 javascript 引擎(就是那个使得Chrome如此之快的东西)所执行的: Node提供了诸如访问网络或是操作文件系统的Javas