nodejs模块中exports和module.exports的区别
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了nodejs模块中exports和module.exports的区别相关的知识,希望对你有一定的参考价值。
通过Node.js的官方API可以看到Node.js本身提供了很多核心模块 http://nodejs.org/api/ ,这些核心模块被编译成二进制文件,可以require(‘模块名‘)去获取;核心模块具有最高的加载优先级(有模块与核心模块同名时会体现)
文件模块访问方式通过require(‘/文件名.后缀‘) require(‘./文件名.后缀‘) requrie(‘../文件名.后缀‘) 去访问,文件后缀可以省略;以"/"开头是以绝对路径去加载,以"./"开头和以"../"开头表示以相对路径加载,而以"./"开头表示同级目录下文件
exports和module.exports;提供了外部访问的接口
讲讲他们的区别
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();
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);
结果:
通过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);
结果:
直接传给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的被覆盖了
文章是学习笔记,如有错误,望指正
以上是关于nodejs模块中exports和module.exports的区别的主要内容,如果未能解决你的问题,请参考以下文章
ES6的export与Nodejs的module.exports