详解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和php实现图片访问实时处理
Jan 05 NodeJs
nodejs搭建本地http服务器教程
Mar 13 NodeJs
nodejs个人博客开发第五步 分配数据
Apr 12 NodeJs
nodejs制作爬虫实现批量下载图片
May 19 NodeJs
深入理解nodejs中Express的中间件
May 19 NodeJs
NodeJS设计模式总结【单例模式,适配器模式,装饰模式,观察者模式】
Sep 06 NodeJs
Nodejs中的JWT和Session的使用
Aug 21 NodeJs
nodejs 使用 js 模块的方法实例详解
Dec 04 NodeJs
NodeJs生成sitemap站点地图的方法示例
Jun 11 NodeJs
nodejs实现百度舆情接口应用示例
Feb 07 NodeJs
nodeJS与MySQL实现分页数据以及倒序数据
Jun 05 NodeJs
nodeJs项目在阿里云的简单部署
Nov 27 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 5.3新特性命名空间规则解析及高级功能
2010/03/11 PHP
PHP使用ODBC连接数据库的方法
2015/07/18 PHP
EarthLiveSharp中cloudinary的CDN图片缓存自动清理python脚本
2017/04/04 PHP
php中的钩子理解及应用实例分析
2019/08/30 PHP
Jquery 获得服务器控件值的方法小结
2010/05/11 Javascript
JS 进度条效果实现代码整理
2011/05/21 Javascript
基于jQuery的烟花效果(运动相关)点击屏幕出烟花
2012/06/14 Javascript
jQuery动态地获取系统时间实现代码
2013/05/24 Javascript
js模拟点击以提交表单为例兼容主流浏览器
2013/11/29 Javascript
JavaScript表格常用操作方法汇总
2015/04/15 Javascript
jquery实现简单手风琴菜单效果实例
2015/06/13 Javascript
JSON字符串转JSON对象
2015/07/31 Javascript
XML文件转化成NSData对象的方法
2015/08/12 Javascript
JS实现的在线调色板实例(附demo源码下载)
2016/03/01 Javascript
Vuejs第八篇之Vuejs组件的定义实例解析
2016/09/05 Javascript
微信小程序 选择器(时间,日期,地区)实例详解
2016/11/16 Javascript
Vue动态实现评分效果
2017/05/24 Javascript
微信小程序自定义导航隐藏和显示功能
2017/06/13 Javascript
详解vue-cli + webpack 多页面实例配置优化方法
2017/07/13 Javascript
JS实现方形抽奖效果
2018/08/27 Javascript
es6函数之严格模式用法实例分析
2020/03/17 Javascript
Python创建一个空的dataframe,并循环赋值的方法
2018/11/08 Python
django数据库自动重连的方法实例
2019/07/21 Python
python中文分词库jieba使用方法详解
2020/02/11 Python
pytorch SENet实现案例
2020/06/24 Python
英国快时尚女装购物网站:PrettyLittleThing
2018/08/15 全球购物
英国最大的滑板品牌选择:Route One
2019/09/22 全球购物
美国Max仓库:Max Warehouse
2020/05/31 全球购物
中专毕业个人的自荐信格式
2013/09/21 职场文书
电话销售经理岗位职责
2013/12/07 职场文书
上课睡觉检讨书
2014/01/28 职场文书
个人工作表现评语
2014/04/30 职场文书
和睦家庭事迹
2014/05/14 职场文书
Python实现信息轰炸工具(再也不怕说不过别人了)
2021/06/11 Python
Python虚拟环境virtualenv是如何使用的
2021/06/20 Python
python 管理系统实现mysql交互的示例代码
2021/12/06 Python