原文标题:Node.js Module – exports vs module.exports

原文链接:http://www.hacksparrow.com/node-js-exports-vs-module-exports.html

exports 和 module.exports 有什么区别?

你一定很熟悉 Node.js 模块中的用来在你的模块中创建函数的 exports 对象,就像下面这样。

创建一个叫做rocker.js的文件:

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

然后可以在另外一个文件中调用 rocker.js :

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

但是,module.exports 到底什么?它是合法的吗?

令人吃惊的是:module.exports 是真实存在的。exports 只不过是 module.exports 的帮手而已。你的模块直接返回返回 module.exports 给调用者,而不是 exports 。所有的 exports 做的工作实际上是收集属性,如果 module.exports 当前没有任何属性,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'

上述例子中的 rocker 模块完全将 exports.name 忽略了,只返回了一个 String 字符串:'ROCK IT!' 。 从这个例子你大概明白了:你的模块并不一定总是一个模块的实例(module instance),它可以是任何合法的 JavaScript 对象——boolean, number, date, JSON, string, function, array 和其他的。你的模块可以是任何你设置的 module.exports 的值。如果你没有明确地为 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 ;如果你只想模块作为一个典型的模块实例(module instance),那么就用exports。

把属性添加到 module.exports 中和添加到 exports 中的结果是一样的。比如像这样:

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

其实和下面的是一样的:

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

但是要注意,他们不是同一个东西。就像之前说的一样,exports 只不过是 module.exports 的帮手而已。话虽如此,exports 还是推荐的对象,除非你想把你模块的对象类型从传统的模块实例(module instance)修改为其他的。

只要你没有使用赋值运算重写 module.exports 对象,任何添加到 module.exports 和 exports 的属性都能够在 require 模块中。

比如这是你的模块中的内容:

module.exports.age = 68;
exports.name = 'Lemmy Kilmister';

下面的代码可以很好的工作:

var rocker = require('./rocker.js');
console.log('%s is %s', rocker.name, rocker.age); // Lemmy Kilmister is 68

但是,如果你在你的模块中重写了 module.exports 中的任何地方,代码便会出错:

module.exports = 'LOL';
module.exports.age = 68;
exports.name = 'Lemmy Kilmister';

或者这样:

module.exports.age = 68;
exports.name = 'Lemmy Kilmister';
module.exports = 'WTF';

顺序没有关系,rocker.age 和 rocker.name 将显示为 undefined。

并且注意:只是因为 module.exports 和 exports 都能输出模块,并不意味这你可以组合使用。我的建议是,坚持使用 exports.*,明白module.exports

我希望这篇文章能帮助你理解exports和module.exports之间的不同,并且能进一步的理解模块在Node.js中是怎么工作的。

(完)

翻译水平有待提高,所翻译的博文并不是按照原文一句一句翻译,而是添加了自己对文章的理解。如有不正之处,欢迎指正!

个人笔记,仅供参考。

参考:

http://www.hacksparrow.com/node-js-exports-vs-module-exports.html

(译)Node.js的模块-exports和module.exports的更多相关文章

  1. Node.js学习之(第二章:exports和module.exports)

    前言 Node中,每个模块都有一个exports接口对象,我们需要把公共的方法或者字符串挂载在这个接口对象中,其他的模块才可以使用. Node.js中只有模块作用域,默认两个模块之间的变量,方法互不冲 ...

  2. node.js模块中exports和module.exports的区别

    Node应用由模块组成,采用CommonJS模块规范. 根据这个规范,每个文件就是一个模块,有自己的作用域.在一个文件里面定义的变量.函数.类,都是私有的,对其他文件不可见. CommonJS规范规定 ...

  3. Node.js模块导出exports 和 module.exports 的区别

    原文: https://blog.csdn.net/Pwiling/article/details/51958693 每一个node.js执行文件,都自动创建一个module对象,同时,module对 ...

  4. Node.js中exports与module.exports的区别

    原文:http://www.hacksparrow.com/node-js-exports-vs-module-exports.html 你肯定对Node.js模块中用来创建函数的exports对象很 ...

  5. node (02 CommonJs 和 Nodejs 中自定义模块)顺便讲讲module.exports和exports的区别 dependencies 与 devDependencies 之间的区别

    CommonJS 规范的提出,主要是为了弥补当前 JavaScript 没有标准的缺陷.它的终极目标就是:提供一个类似 Python,Ruby 和 Java 语言的标准库,而不只是停留在小脚本程序的阶 ...

  6. Node.js之exports与module.exports

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

  7. node.js中的exports和module.exports

    不同的编程语言都有各自的代码组织和复用的方式,如.net.php中的命名空间,python中的import,ruby中的module等,来避免命名空间污染.一直都没搞清楚node中的exports和m ...

  8. Node.js exports与module.exports的关系

    今天搜索module.exports时看到CNode社区上发的Hack Sparrow一篇相关文章的链接 Node.js Module – exports vs module.exports 一篇5年 ...

  9. 理解node模块的exports和module.exports

    exports是module.exports的引用,即var exports = module.exports.在一个模块的开头,这两个值都指向同一个空对象:exports = module.expo ...

随机推荐

  1. JQ兼容性问题

    checkbox操作 1:设置为选中状态   $(this).prop("checked", true); 2:判断是否选中     $(this).is(":check ...

  2. 《转》JAVA并发编程:volatile关键字解析

    volatile这个关键字可能很多朋友都听说过,或许也都用过.在Java 5之前,它是一个备受争议的关键字,因为在程序中使用它往往会导致出人意料的结果.在Java 5之后,volatile关键字才得以 ...

  3. ECC(Error Checking and Correction)校验和纠错

    ECC的全称是 Error Checking and Correction or Error correction Coding,是一种用于差错检测和修正的算法.上一节的BBM中我们提到过,NAND闪 ...

  4. 浅谈Java泛型中的extends和super关键字(转)

    通配符 在本文的前面的部分里已经说过了泛型类型的子类型的不相关性.但有些时候,我们希望能够像使用普通类型那样使用泛型类型: 向上造型一个泛型对象的引用 向下造型一个泛型对象的引用 向上造型一个泛型对象 ...

  5. 关于crontab笔记

    如下所示,一般crontab文件里面的定时任务格式如下所示: 59 23 * * * /home/oracle/scripts/alert_log_archive.sh >/dev/null 2 ...

  6. 【玩转Ubuntu】08. Linux报错:Syntax error: "(" unexpected解决办法

    问题: 在MAC上写了一段shell脚本,放到Ubuntu上运行总是报下面这个错误,单步调试都是对的,就是直接运行会报错. bixiaopeng@ubuntu:~/package$ sh packag ...

  7. redis 缓存技术与memcache的最大差别

    1 什么是redis  redis是一个key-value存储系统.和Memcached类似,它支持存储的value类型相对很多其它,包含string(字符串).list(链表).set(集合)和zs ...

  8. 用JS判断两个数字的大小

    js中的var定义的变量默认是字符串,如果单纯的比较字符串的话,会出现错误,需要先转化为int类型在做比较. [备注:110和18在你写的程序中是18大的,因为 这两个数都是字符串,而1和1相等之后比 ...

  9. 读取excel出现空值

    表格里某列假如混杂了数字和字符就会有可能部分读取为空,连接Excel方法如下 string strConn = 'Provider=Microsoft.Jet.OLEDB.4.0;' 'Data So ...

  10. objective-C学习笔记(四)函数成员:方法(函数)

    函数分为:  全局函数(C语言函数) 成员函数(OBJC方法):实例方法 “-” 和类方法“+”的区别 //这里要区别静态变量(类变量).全局函数.常量的区别 OBJC里面,所有方法默认为公有方法.没 ...