Node.js遵循CommonJS规范的模块机制,一个JS文件即被视为一个独立的模块。在模块内部可以通过2种方式导出模块:

  1. module.exports
  2. exports

module.exports是一个对象引用,这个对象具有以下特征:

  1. 默认值:{}
  2. 模块始终导出该对象

exports也是一个对象引用,它与module.exports默认指向同一个对象

console.log(module.exports === exports);   // true
复制代码

所以如果我们只是向module.exports(或exports)追加需要导出的内容时,采用哪种方式都可以,因为两者始终指向同一个对象

module.exports.a = 1;console.log(module.exports);    // { a: 1 }
console.log(exports);           // { a: 1 }exports.b = 2;
console.log(module.exports);    // { a: 1, b: 2 }
console.log(exports);           // { a: 1, b: 2 }
复制代码

但如果给module.exports(或exports)重新赋值,那么就会出现一些意想不到的效果。假设我们使用如下的方式导出模块

// foo.js
module.exports = {a: 1
}
exports.b = 2;
复制代码
// main.js
var foo = require('./foo');console.log(foo); // { a: 1 },导出的对象并不包含b
复制代码

出现上面结果的原因是:module.exports在被’=’赋值时,实际上是新生成了一个{a: 1}对象,并且断开module.exports与默认对象{}的引用,从而指向{a: 1}这个新生成的对象;然而exports此时还是指向默认对象{}exports.b = 2;实际上是向这个默认对象添加了b,而不是module.exports所指的那个对象;并且Node模块最终只会导出module.exports所指向的那个对象(或值),所以就出现了上面的结果。

概括一句话就是:给模块对象的重新复制导致module.exports与exports分别指向了不同的对象

‘最好的证明就是用代码演示’,所以我们代码证明一下上面的分析

// foo.js
module.exports = {a: 1
}
exports.b = 2;console.log(module.exports === exports);  // false
console.log(module.exports);                // { a: 1 }
console.log(exports);                       // { b: 2 }
复制代码
// main.js
var foo = require('./foo');console.log(foo); // { a: 1 }
复制代码

那么是否有办法修补上面的问题呢?答案是:有的,问题的关键是:module.exports与exports指向了不同的对象,那么我们就将它们指回同一个对象

// foo.js
module.exports = {a: 1
}console.log(module.exports === exports);    // falseexports = module.exports;
exports.b = 2;console.log(module.exports === exports);  // true
console.log(module.exports);                // { a: 1, b: 2 }
console.log(exports);                       // { a: 1, b: 2 }
复制代码

所以,导出模块时我们最好采用如下形式:

exports = module.exports = {a: 1
}console.log(module.exports === exports);    // true
console.log(module.exports);                // { a: 1 }
console.log(exports);                       // { a: 1 }
复制代码

以上就是对module.exports与exports两者关系的浅显分析,希望对大家有所帮助,如有错误,欢迎指正~

原文地址:www.guoyunfeng.com/2018/06/06/…

浅析Node模块中module.exports与exports的关系相关推荐

  1. module.exports和exports使用误区

    module.exports和exports使用误区 使用require()模块时,得到的永远都是module.exports指向的对象 1.误区一 exports.username = 'zs' e ...

  2. nodeJS 中文API node.js 中文文档

    Node.js Manual & Documentation Table Of Contents Synopsis 概要 Global Objects 全局对象 global process ...

  3. node.js中exports与module.exports的区别分析

    前言 关于Node.js中的exports和module.exports,很多时候都比较容易让人混淆,弄不清楚两者间的区别.那么我们就从头开始理清这两者之间的关系. 来源 在开发Node.js应用的时 ...

  4. (node中)module.exports 和exports的区别

    (node中使用)module.exports 和exports的区别是什么? 用一句话来说明就是,require只会去引用module.exports这个对象的导出,不会引用exports对象的,而 ...

  5. Node.js中exports、module.exports、require之间的关系

    Node中的js文件 Node中的每个JS文件都是一个单独的模块,模块中包含的核心变量:exports.module.exports.require nodejs中module文档 // 插入图片 E ...

  6. node.js中exports与module.exports的区别

    CommonJS Node应用是由模块组成的,采用的是CommonJS模块规范. 根据规范一个文件就是一个模块,有自己单独的作用域,在一个文件中定义的变量,函数,类都是私有的,对其他的文件不可见. 根 ...

  7. Node.js 中的 module.exports 与 exports

    介绍 module:每个模块中都有 module 对象,存放了当前模块相关的信息: module.exports:模块导出的内容: exports:默认情况下,exports 和 module.exp ...

  8. Node.js 中 exports 和 module.exports 的区别

    每一个模块中都有一个 module 对象, module 对象中有一个 exports 对象 我们可以把需要导出的成员都放到 module.exports 这个接口对象中,也就是 module.exp ...

  9. Node.js中exports和moudle.exports

    在Node.js模块化中,首先了解模块化作用域. 和函数作用域类似,在自定义模块中,定义的变量.方法等成员,只能在当前模块内被访问,这种模块级别的访问限制,叫做模块作用域. 可以防止 全局作用域的变量 ...

最新文章

  1. Spring Cloud 中国社区一周年技术沙龙-北京站
  2. kibana智能检索发送多次_msearch —— 配置index pattern,同时设置时间段,就知道到底是在哪些索引里去查找数据了...
  3. signature=3ba70fa0be2ca50c615373e5495718b1,翻译文化观与翻译改写
  4. 借助LDA主题分析的短文本相似性计算 - 综述帖
  5. Linux下crontab(自动重启)的格式备忘
  6. php发请求的方法,php发送http请求的几种方法
  7. (23)VHDL实现乘法器
  8. Https是如何工作的?
  9. 多线程的实现方式01 Thread
  10. 一文看懂Python列表表达式及高阶函数如lambda, zip, enumerate, map和filter方法
  11. 解决idea使用maven打自定义jar缺失
  12. 【问】安装SQL 2012R2时提示NetFx3
  13. CodeBlock13.12对gcc与g++的更新
  14. 通过ip地址连接局域网内的打印机(win7、win10)
  15. 关于在word中安装Mathtype
  16. https安全认证流程简介
  17. oracle 系统资源正忙,oracle提示资源正忙怎么解决?oracle资源正忙解决方法
  18. js如何往数组Array中添加删除元素
  19. 2021年起重机械指挥考试题及起重机械指挥模拟考试
  20. 聚类算法K-Means K-Medoids GMM Spectral clustering,Ncut

热门文章

  1. 风口上的政府大数据 需要消除“大误区”
  2. Spring中ClassPathXmlApplicationContext类的简单使用
  3. VS恢复默认设置的2种方法
  4. iOS 开发判断手机型号
  5. 打开u盘时提示是否要将其格式化的提示
  6. nodejs获取当前url和url参数值
  7. netscaler密码恢复
  8. 如何将MP3格式音乐转换成M4R格式
  9. hdu 4945 2048(DP)
  10. 企业运营对 DevOps 的「傲慢与偏见」