浅析Node模块中module.exports与exports的关系
Node.js遵循CommonJS规范的模块机制,一个JS文件即被视为一个独立的模块。在模块内部可以通过2种方式导出模块:
- module.exports
- exports
module.exports是一个对象引用,这个对象具有以下特征:
- 默认值:{}
- 模块始终导出该对象
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的关系相关推荐
- module.exports和exports使用误区
module.exports和exports使用误区 使用require()模块时,得到的永远都是module.exports指向的对象 1.误区一 exports.username = 'zs' e ...
- nodeJS 中文API node.js 中文文档
Node.js Manual & Documentation Table Of Contents Synopsis 概要 Global Objects 全局对象 global process ...
- node.js中exports与module.exports的区别分析
前言 关于Node.js中的exports和module.exports,很多时候都比较容易让人混淆,弄不清楚两者间的区别.那么我们就从头开始理清这两者之间的关系. 来源 在开发Node.js应用的时 ...
- (node中)module.exports 和exports的区别
(node中使用)module.exports 和exports的区别是什么? 用一句话来说明就是,require只会去引用module.exports这个对象的导出,不会引用exports对象的,而 ...
- Node.js中exports、module.exports、require之间的关系
Node中的js文件 Node中的每个JS文件都是一个单独的模块,模块中包含的核心变量:exports.module.exports.require nodejs中module文档 // 插入图片 E ...
- node.js中exports与module.exports的区别
CommonJS Node应用是由模块组成的,采用的是CommonJS模块规范. 根据规范一个文件就是一个模块,有自己单独的作用域,在一个文件中定义的变量,函数,类都是私有的,对其他的文件不可见. 根 ...
- Node.js 中的 module.exports 与 exports
介绍 module:每个模块中都有 module 对象,存放了当前模块相关的信息: module.exports:模块导出的内容: exports:默认情况下,exports 和 module.exp ...
- Node.js 中 exports 和 module.exports 的区别
每一个模块中都有一个 module 对象, module 对象中有一个 exports 对象 我们可以把需要导出的成员都放到 module.exports 这个接口对象中,也就是 module.exp ...
- Node.js中exports和moudle.exports
在Node.js模块化中,首先了解模块化作用域. 和函数作用域类似,在自定义模块中,定义的变量.方法等成员,只能在当前模块内被访问,这种模块级别的访问限制,叫做模块作用域. 可以防止 全局作用域的变量 ...
最新文章
- Spring Cloud 中国社区一周年技术沙龙-北京站
- kibana智能检索发送多次_msearch —— 配置index pattern,同时设置时间段,就知道到底是在哪些索引里去查找数据了...
- signature=3ba70fa0be2ca50c615373e5495718b1,翻译文化观与翻译改写
- 借助LDA主题分析的短文本相似性计算 - 综述帖
- Linux下crontab(自动重启)的格式备忘
- php发请求的方法,php发送http请求的几种方法
- (23)VHDL实现乘法器
- Https是如何工作的?
- 多线程的实现方式01 Thread
- 一文看懂Python列表表达式及高阶函数如lambda, zip, enumerate, map和filter方法
- 解决idea使用maven打自定义jar缺失
- 【问】安装SQL 2012R2时提示NetFx3
- CodeBlock13.12对gcc与g++的更新
- 通过ip地址连接局域网内的打印机(win7、win10)
- 关于在word中安装Mathtype
- https安全认证流程简介
- oracle 系统资源正忙,oracle提示资源正忙怎么解决?oracle资源正忙解决方法
- js如何往数组Array中添加删除元素
- 2021年起重机械指挥考试题及起重机械指挥模拟考试
- 聚类算法K-Means K-Medoids GMM Spectral clustering,Ncut