详解nodejs中exports和module.exports的区别


Posted in NodeJs onFebruary 17, 2017

require 用来加载代码,而 exports 和 module.exports 则用来导出代码。但很多新手可能会迷惑于 exports 和 module.exports 的区别,为了更好的理解 exports 和 module.exports 的关系,我们先来巩固下 js 的基础。示例:

app.js

var a = {name: 'nswbmw 1'};
var b = a;
console.log(a);
console.log(b);
b.name = 'nswbmw 2';
console.log(a);
console.log(b);
var b = {name: 'nswbmw 3'};
console.log(a);
console.log(b);

运行 app.js 结果为:

{ name: 'nswbmw 1' }
{ name: 'nswbmw 1' }
{ name: 'nswbmw 2' }
{ name: 'nswbmw 2' }
{ name: 'nswbmw 2' }
{ name: 'nswbmw 3' }

解释一下:a 是一个对象,b 是对 a 的引用,即 a 和 b 指向同一个对象,即 a 和 b 指向同一块内存地址,所以前两个输出一样。当对 b 作修改时,即 a 和 b 指向同一块内存地址的内容发生了改变,所以 a 也会体现出来,所以第三、四个输出一样。当对 b 完全覆盖时,b 就指向了一块新的内存地址(并没有对原先的内存块作修改),a 还是指向原来的内存块,即 a 和 b 不再指向同一块内存,也就是说此时 a 和 b 已毫无关系,所以最后两个输出不一样。

明白了上述例子后,我们进入正题。

我们只需知道三点即可知道 exports 和 module.exports 的区别了:

  • exports 是指向的 module.exports 的引用
  • module.exports 初始值为一个空对象 {},所以 exports 初始值也是 {}
  • require() 返回的是 module.exports 而不是 exports

所以:我们通过

var name = 'nswbmw';
exports.name = name;
exports.sayName = function() {
 console.log(name);
}

给 exports 赋值其实是给 module.exports 这个空对象添加了两个属性而已,上面的代码相当于:

var name = 'nswbmw';
module.exports.name = name;
module.exports.sayName = function() {
 console.log(name);
}

我们通常这样使用 exports 和 module.exports

一个简单的例子,计算圆的面积:

使用 exports

app.js

var circle = require('./circle');
console.log(circle.area(4));

circle.js

exports.area = function(r) {
 return r * r * Math.PI;
}

使用 module.exports

app.js

var area = require('./area');
console.log(area(4));

area.js

module.exports = function(r) {
 return r * r * Math.PI;
}

上面两个例子输出是一样的。你也许会问,为什么不这样写呢?

app.js

var area = require('./area');
console.log(area(4));

area.js

exports = function(r) {
 return r * r * Math.PI;
}

运行上面的例子会报错。这是因为,前面的例子中通过给 exports 添加属性,只是对 exports 指向的内存做了修改,而

exports = function(r) {
 return r * r * Math.PI;
}

其实是对 exports 进行了覆盖,也就是说 exports 指向了一块新的内存(内容为一个计算圆面积的函数),也就是说 exports 和 module.exports 不再指向同一块内存,也就是说此时 exports 和 module.exports 毫无联系,也就是说 module.exports 指向的那块内存并没有做任何改变,仍然为一个空对象 {} ,也就是说 area.js 导出了一个空对象,所以我们在 app.js 中调用 area(4) 会报 TypeError: object is not a function 的错误。

所以,一句话做个总结:当我们想让模块导出的是一个对象时,exports 和 module.exports 均可使用(但 exports也不能重新覆盖为一个新的对象),而当我们想导出非对象接口时,就必须也只能覆盖 module.exports。

我们经常看到这样的用写法:

exports = module.exports = somethings;

上面的代码等价于

module.exports = somethings;
exports = module.exports;

原因也很简单,module.exports = somethings 是对 module.exports 进行了覆盖,此时 module.exports 和 exports 的关系断裂,module.exports 指向了新的内存块,而 exports 还是指向原来的内存块,为了让 module.exports 和 exports 还是指向同一块内存或者说指向同一个 “对象”,所以我们就 exports = module.exports。

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持三水点靠木!

NodeJs 相关文章推荐
nodejs获取本机内网和外网ip地址的实现代码
Jun 01 NodeJs
Nodejs进阶:如何将图片转成datauri嵌入到网页中去实例
Nov 21 NodeJs
使用nodejs+express实现简单的文件上传功能
Dec 27 NodeJs
Nodejs异步回调之异常处理实例分析
Jun 22 NodeJs
基于nodejs的雪碧图制作工具的示例代码
Nov 05 NodeJs
NodeJs 文件系统操作模块fs使用方法详解
Nov 26 NodeJs
基于Koa(nodejs框架)对json文件进行增删改查的示例代码
Feb 02 NodeJs
Nodejs实现的操作MongoDB数据库功能完整示例
Feb 02 NodeJs
nodejs中实现修改用户路由功能
May 24 NodeJs
Nodejs监听日志文件的变化的过程解析
Aug 04 NodeJs
Nodejs在局域网配置https访问的实现方法
Oct 17 NodeJs
Nodejs+Socket.io实现通讯实例代码
Feb 13 #NodeJs
Nodejs高扩展性的模板引擎 functmpl简介
Feb 13 #NodeJs
Nodejs 发送Post请求功能(发短信验证码例子)
Feb 09 #NodeJs
Nodejs实现短信验证码功能
Feb 09 #NodeJs
Express与NodeJs创建服务器的两种方法
Feb 06 #NodeJs
使用nodejs下载风景壁纸
Feb 05 #NodeJs
nodeJs链接Mysql做增删改查的简单操作
Feb 04 #NodeJs
You might like
php生成文件
2007/01/15 PHP
PHP遍历数组的几种方法
2012/03/22 PHP
PHP asXML()函数讲解
2019/02/03 PHP
FormValid0.5版本发布,带ajax自定义验证例子
2007/08/17 Javascript
jQuery 实现自动填充邮箱功能(带下拉提示)
2014/10/14 Javascript
node.js中的fs.fchown方法使用说明
2014/12/16 Javascript
BOOTSTRAP时间控件显示在模态框下面的bug修复
2015/02/05 Javascript
js兼容pc端浏览器并有多种弹出小提示的手机端浮层控件实例
2015/04/29 Javascript
avalonjs制作响应式瀑布流特效
2015/05/06 Javascript
JavaScript学习小结(一)——JavaScript入门基础
2015/09/02 Javascript
js实现图片上传并正常显示
2015/12/19 Javascript
详解JavaScript的AngularJS框架中的作用域与数据绑定
2016/03/04 Javascript
Vue.JS入门教程之列表渲染
2016/12/01 Javascript
Bootstrap面板使用方法
2017/01/16 Javascript
js中的触发事件对象event.srcElement与event.target详解
2017/03/15 Javascript
bmob js-sdk 在vue中的使用教程
2018/01/21 Javascript
微信小程序解除10个请求并发限制
2018/12/18 Javascript
[57:29]Alliance vs KG 2019国际邀请赛小组赛 BO2 第二场 8.16
2019/08/17 DOTA
Python3 读、写Excel文件的操作方法
2018/10/20 Python
python 处理telnet返回的More,以及get想要的那个参数方法
2019/02/14 Python
Python如何爬取实时变化的WebSocket数据的方法
2019/03/09 Python
wxpython实现按钮切换界面的方法
2019/11/19 Python
OpenCV+Python--RGB转HSI的实现
2019/11/27 Python
ipython jupyter notebook中显示图像和数学公式实例
2020/04/15 Python
解决tensorflow读取本地MNITS_data失败的原因
2020/06/22 Python
scrapy头部修改的方法详解
2020/12/06 Python
解决virtualenv -p python3 venv报错的问题
2021/02/05 Python
世界著名的顶级牛排:Omaha Steak(奥马哈牛排)
2016/09/20 全球购物
董事长秘书职责
2014/01/31 职场文书
培训讲师岗位职责
2014/04/13 职场文书
生产工厂门卫岗位职责
2014/09/26 职场文书
2016圣诞节贺卡寄语
2015/12/07 职场文书
微信小程序用户授权最佳实践指南
2021/05/08 Javascript
详细聊聊关于Mysql联合查询的那些事儿
2021/10/24 MySQL
国际最新研究在陨石中发现DNA主要成分 或由陨石带来地球
2022/04/29 数码科技
鸿蒙3.0体验感怎么样? 鸿蒙3.0系统评测向
2022/08/14 数码科技