nodejs中exports和module.exports区别

来源:互联网 发布:精通c语言能做黑客吗 编辑:程序博客网 时间:2024/05/01 19:55

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

你肯定熟悉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的辅助工具。你的模块最终返回给调用者的是module.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');};
另外一个调用者文件内容如下,并执行代码:

var rocker = require('./rocker.js');rocker.name(); // TypeError: Object ROCK IT! has no method 'name'
rocker模块完全忽略exports.name,只是返回一个"ROCK IT!"字符串。从这你也可以看出,模块不是必须是个“模块实例”。模块可以是任意合法的JavaScript对象-boolean,number,date,JSON,string,function和array等。模块无所谓是否设置module.exports。如果你没有显式地设置module.exports,那么exports的属性将会附加到module.exports上,然后返回。

在这种情形下,模块是个class:

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.name = function() {    console.log('My name is Lemmy Kilmister');};

但是,需要注意的是,它们不是个一件事。正如之前提到的,module.exports是本尊,exports只是辅助工具而已。话虽如此,如果你不计划改变模块对象类型从传统的模块实例至其它,exports是个推荐使用的对象。

如果,你没有对module.exports对象进行赋值,任何附加在module.exports和exports上内容可以可用的。

例如,你的模块中这样写:

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会是为定义。

同时,只是因为module.exports.age和exports.name都被导出,这不意味这你可以结合两者一起使用。我推荐使用exports.*,同时注意module.exports.*。

0 0
原创粉丝点击