设为首页 收藏本站
查看: 824|回复: 0

[经验分享] nodejs模块中exports和module.exports的区别

[复制链接]

尚未签到

发表于 2017-2-24 10:15:06 | 显示全部楼层 |阅读模式
  通过Node.js的官方API可以看到Node.js本身提供了很多核心模块 http://nodejs.org/api/ ,这些核心模块被编译成二进制文件,可以require('模块名')去获取;核心模块具有最高的加载优先级(有模块与核心模块同名时会体现),如:



var fs=require('fs');
var http=require('http')
  文件模块访问方式通过require('/文件名.后缀') require('./文件名.后缀') requrie('../文件名.后缀') 去访问,文件后缀可以省略;以"/"开头是以绝对路径去加载,以"./"开头和以"../"开头表示以相对路径加载,而以"./"开头表示同级目录下文件,如:



var myadd=require('./add');   //本目录下的add.js
  exports和module.exports;提供了外部访问的接口
  (本文讲exports和module.exports,是对外暴露文件,再引用,属于文件模块。核心模块由node写好,直接引用就行)
  讲讲他们的区别
  1、模块导入会缓存,写了多次导入,只会导一次。
  即使导入的路径不一样。它缓存是指实际文件名,并不会因为传入的路径形式不一样而认会是不同的文件



1 var outputVal  = 0;     //输出值
2 var increment = 1;    //增量
3 /* 设置输出值 */
4 function seOutputVal (val) {
5     outputVal = val;
6 }
7 /* 设置增量 */
8 function setIncrement(incrementVal){
9     increment = incrementVal;
10 }
11 /* 输出 */
12 function printNextCount()
13 {
14     outputVal += increment;
15     console.log(outputVal) ;
16 }
17 function printOutputVal() {
18     console.log(outputVal);
19 }
20 exports.seOutputVal = seOutputVal;
21 exports.setIncrement = setIncrement;
22 module.exports.printNextCount = printNextCount;



1 /*
2     一个Node.js文件就是一个模块,这个文件可能是Javascript代码、JSON或者编译过的C/C++扩展。
3     重要的两个对象:
4     require是从外部获取模块
5     exports是把模块接口公开
6 */
7 var counter = require('./1_modules_custom_counter');
8 console.log('第一次调用模块[1_modules_custom_counter]');
9 counter.seOutputVal(10);               //设置从10开始计数
10 counter.setIncrement (10);             //设置增量为10
11 counter.printNextCount();
12 counter.printNextCount();
13 counter.printNextCount();
14 counter.printNextCount();
15 /*
16     require多次调用同一模块不会重复加载
17 */
18 var counter = require('./1_modules_custom_counter');
19 console.log('第二次调用模块[1_modules_custom_counter]');
20 counter.printNextCount();
DSC0000.png

  2、通过exports和module.exports对外公开的方法都可以访问,但有区别
  module.exports才是真正的接口,exports只不过是它的一个辅助工具。 最终返回给调用的是module.exports而不是exports。
所有的exports收集到的属性和方法,都赋值给了Module.exports。当然,这有个前提,就是module.exports本身不具备任何属性和方法。
如果,module.exports已经具备一些属性和方法,那么exports收集来的信息将被忽略。
  我把exports和 module.exports都打印出来看看究竟
  ①  (虽然这样在引入模块时会报错,但这一步能说明问题,后面说原因)



1 var counter  = 0;
2 exports.temp  = function(){
3     counter += 10;
4     this.printNextCount = function()
5     {
6         console.log(counter);
7     }
8 }
9 var isEq = (exports === module.exports);
10 console.log(exports);
11 console.log(module.exports);
12 console.log(isEq);
  结果:
DSC0001.png

  通过exports导出的方法,会传递给module.exports。二者没区别
  ②



1 var counter  = 0;
2 module.exports = function(){
3     counter += 10;
4     this.printNextCount = function()
5     {
6         console.log(counter);
7     }
8 }
9 var isEq = (exports === module.exports);
10 console.log(exports);
11 console.log(module.exports);
12 console.log(isEq);
  结果:
DSC0002.png

  直接传给module.exports,那exports就说明都没有,二者不相等了。
  ③:注意,导入时有点区别。和上面第一大点不一样
  如这里的②



1  var  Counter = require('./  ');
2  var  counterObj = new Counter();
3  counterObj.printNextCount();
  而第一大点可以直接这样:



1  var counter = require('./1_modules_custom_counter');
2  console.log('第二次调用模块[1_modules_custom_counter]');
3  counter.printNextCount();
  就是要new一个对象!
  因为导出的文件中的函数变成了成员方法,所以要new一个对象,再调用成员方法。
  说明①不可行的原因:当我在别的文件调用它时,无论是直接调用,还是new一个对象再调用,都报错!
  所以,要遵循这两点
  1.最好别分别定义module.exports和exports
  2.NodeJs开发者建议导出对象用module.exports,导出多个方法和变量用exports
  3、exports和module.exports覆盖
  直接上代码,看谁留下,谁消失



1 var counter  = 0;
2 exports.printNextCount = function()
3     {
4     counter+=2;
5         console.log(counter);
6     }
7 module.exports = function(){
8 counter+=10;
9 this.printNextCount=function(){
10 console.log(counter)
11 }
12
13 }
14 var isEq = (exports === module.exports);
15 console.log(exports);
16 console.log(module.exports);
17 console.log(isEq);
  想想都知道谁厉害。
  引用该模块:
  ①报错,说明exports的消失了



1 var counter = require('./test3');
2 counter.printNextCount();
  ②留下了。



1 var counter = require('./test3');
2 var counterObj=new counter()
3 counterObj.printNextCount();
  结果,输出了它成功导出的对象函数值;前面两个是两个接口收集到的东西,最后exports的被覆盖了
DSC0003.png

  exports仅仅是module.exports的一个地址引用。nodejs只会导出module.exports的指向,如果exports指向变了,那就仅仅是exports不在指向module.exports,于是不会再被导出
  相当于:a和b指向同一块内存,b是a的地址引用



1  var a = new Object();//a相当于module.exports
2  var b = a; //b相当于exports
  覆盖,也就是a已经赋值了,但b又被赋了别的值。这时候,b就是叛变了,就指向了一块新的地址了。
  而模块引用是要用module.exports来引用,所以指向新地址的exports不起作用了。
  文章是学习笔记,如有错误,望指正

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-346501-1-1.html 上篇帖子: Nodejs建站笔记 下篇帖子: nodejs教程之环境安装及运行
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表