初识Nodejs的exports和module.exports

文本参考了这篇原创文章:

http://qifuguang.me/2015/11/11/揭秘Node-js中exports和module-exports/


Nodejs使用模块化工具管理的原理,每个独立的js文件都可以看做是一个模块,每个模块中都隐含着exports和和module.exports两个对象。

系统自动给nodejs 文件增加2个变量 exports 和 module, module 又有一个属性 exports, 这个exports 属性指向一个空对象 {}; 同时 exports这个变量也指向了这个空对象{};

首先我们得先摆出两条不变的真理:

  1. exports一开始是指向module.exports的;
  2. 通过require得到的是module.exports中的内容,而不是exports的内容;

exports和module这两个对象是所有Node.js类型的文件中都默认隐式存在的,比如我们新建一个test.js文件:

 
 
console.log(exports);
console.log(module); 终端显示结果: {} Module {   id: '.',   exports: {},   parent: null,   filename: 'C:\\nodejs\\workspace\\exports_module.exports.js',   loaded: false,   children: [],   paths:    [ 'C:\\nodejs\\workspace\\node_modules',      'C:\\nodejs\\node_modules',      'C:\\node_modules' ] }

可以看到,test.js文件中并未声明exports和module对象,但是它们确实存在。并且可以看到,exports的初始值是{},而module的初始值有一大串属性,其中还包含一个exports属性,它的初始值也是{}。

实际上,一开始exports就是指向module.exports的,引用关系如下图:


然后,我们来创建一个my_module.js文件:

 
 
// 为exports增加一个属性sayHello(属性值为函数),指向未变(还是指向module.exports)
exports.sayHello = function() {     console.log('Hello world!');     // 查看exports和module.exports     console.log(exports);     console.log(module.exports); }
再在同一个目录下创建app.js文件:

 
 
myModule = require('./my_module');
myModule.sayHello(); 终端显示结果: Hello world! { sayHello: [Function] } { sayHello: [Function] }

所以现在exports和module.exports是这样的:


接着,我们再来创建一个my_module2.js文件:

 
 
// exports被重新分配了一块新的内存,而不再指向module.exports了。 exports = {
sayHello: function() {console.log('Hello world!');}
} console.log(exports);

然后将app.js文件修改为以下内容:

 
 
myModule = require('./my_module2');
console.log('module.exports:');
console.log(module.exports);
myModule.sayHello(); 终端运行出错了!!! C:\nodejs\workspace\app.js:4 myModule.sayHello();          ^ TypeError: myModule.sayHello is not a function     at Object.<anonymous> (C:\nodejs\workspace\app.js:4:10)     at Module._compile (module.js:409:26)     at Object.Module._extensions..js (module.js:416:10)     at Module.load (module.js:343:32)     at Function.Module._load (module.js:300:12)     at Function.Module.runMain (module.js:441:10)     at startup (node.js:139:18)     at node.js:974:3

这个时候,exports和module.exports的状态是这样的:


将app.js中的myModule.sayHello();注释掉,然后重新运行app.js,输出结果如下:

{ sayHello: [Function] }
module.exports:
{}

从输出中也可以看到,此时的module.exports={},所以肯定找不到sayHello函数,那必然报错!

而exports的输出为:{ sayHello: [Function] }


结论:

1.最好别分别定义module.exports和exports

2.NodeJs开发者建议导出对象用module.exports,导出多个方法和变量用exports

3.require返回的是module.exports,在module.exports上可以设置函数、对象实例、基本类型的变量等,因此,一般就是module.exports作为模块的导出就行了。

如果想用exports作为模块的返回,那么就为它设置一个属性,并且不要在module.exports上设置同名的属性。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值