Node.js中module.export与export有何区别
沉沙 2018-07-19 来源 : 阅读 624 评论 0

摘要:本篇Node.js教程探讨了Node.js中module.export与export有何区别,希望阅读本篇文章以后大家有所收获,帮助大家对Node.js的理解更加深入。

对module.exports和exports的一些理解

可能是有史以来最简单通俗易懂的有关Module.exports和exports区别的文章了。

exports = module.exports = {};

所以module.exports和exports的区别就是var a={}; var b=a;,a和b的区别

看起来木有什么太大区别,但实际用起来的时候却又有区别,这是为啥呢,请听我细细道来

关于Module.exports和exports有什么区别,网上一搜一大把,但是说的都太复杂了…
听说exports是Module.exports对象的一个引用(reference)^1,什么是引用?!…_(:з」∠)_

当然啦,如果要彻底理解这两个导出的区别,最好肯定是去看源码,看看都是怎么封装的,功力深厚的童鞋应该一看就懂了。不过,源码我也是看不懂的…(ಥ_ಥ)

但是最近感觉杂七杂八看了好多文章做了好多实验之后,像是打开了任督二脉,机智的我好像有点上道了…

module

首先要明确的一点,module是一个对象 {Object}。
当你新建一个文件,比如mo.js,文件内容如下:

1

console.log(module);

然后在CMD里执行这个文件node mo.js,就能看到module其实是一个Module实例,你可以这么理解,NodeJS中定义了一个Module类,这个类中有很多属性和方法,exports是其中的一个属性:

function Module {

  id : 'blabla',
  exports : {},
  blabla...
}

当每个js文件在执行或被require的时候,NodeJS其实创建了一个新的实例var module = new Module(),这个实例名叫module。
这也就是为什么你并没有定义module这个变量,却能console.log出来而不会报错的原因。

module.exports

假设我有一个JS文件内容如下:

console.log(module); //你会看到Module中的exports为空对象{}module.exports = {

  print : function(){console.log(12345)}

}console.log(module); //你会看到Module中的exports对象已经有了print()方法

有了上面的基础,很容易理解module.export其实是给Module实例中的exports对象中添加方法/属性。

exports

通常使用exports的时候,是这么用的:

exports.print = function(){console.log(12345)}

假设我有一个JS文件内容如下:

console.log(module); //你会看到Module中的exports为空对象{}console.log(exports); //你会看到Module中的exports为空对象{}module.exports = {

  print : function(){console.log(12345)}

}console.log(module); //你会看到Module中的exports对象有了print()方法

exports.name = '小白妹妹';console.log(module); //你会看到Module中的exports对象不仅有了print()方法,还有了name属性

由此也能看出,传说中的exports其实是module.exports的引用,你可以这么理解,NodeJS在你的代码之前悄悄的加了以下代码:

var module = new Module();

var exports = module.exports;

这也就是为什么你并没有定义exports这个变量,却能console.log出来而不会报错的原因。

require

当你从外部调用某个模块,require其实是在require什么?^2
require的时候NodeJS会到处去找有没有这个模块,如果有,return的就是module.exports里的东东。

DOs & DONTs

· √你可以这样:

module.exports.name = '小白妹妹';

exports.age = 10;

module.exports.print = function(){console.log(12345)};

· 如果只是使用.来添加属性和方法,module.exports和exports混用是完全可以的,这种情况下,感觉exports就是给懒人用的…毕竟能少写几个7个字符呢!

· √也可以这样:

module.exports = {

name = '小白妹妹';

};

exports.age = 10;

module.exports.print = function(){console.log(12345)};

· 

· ×但不可以这样:

module.exports = {

name = '小白妹妹';

};

exports = {age:10}; // exports现在是{age:10}这个对象的引用,不再是module.exports的引用了

console.log(module); //你会看到Module的exports中只有name属性!!!

· 

· ×也不可以这样:

exports.age = 10;

console.log(module); //你会看到Module的exports中多了age属性

module.exports = {

name = '小白妹妹';

};

console.log(module); //你会看到Module的exports中还是只有name属性!!!

· 

总结

· 还是那一句话,module.exports和exports的区别就是var a={}; var b=a;,a和b的区别

· 改变exports的指向后所添加的exports.xxx都是无效的。因为require返回的只会是module.exports

· 不能在使用了exports.xxx之后,改变module.exports的指向。因为exports.xxx添加的属性和方法并不存在于module.exports所指向的新对象中。

· 对于要导出的属性,可以简单直接挂到exports对象上

· 对于类,为了直接使导出的内容作为类的构造器可以让调用者使用new操作符创建实例对象,应该把构造函数挂到module.exports对象上,不要和导出属性值混在一起


本文由职坐标整理发布,欢迎关注职坐标Node.js频道,学习更多WEB前端知识!

本文由 @沉沙 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程