nodejs里的module.exports和exports

在node.js中我们可以使用module.exports和exports导出模块,设置导出函数、数组、变量等等

为什么可以用这两个模块?

或者直接问,node.js的模块功能是怎么实现的。
这样得益于javascript是函数性的语言,并支持闭包。

js的闭包

直接看w3cschool吧,感觉讲的挺好的:js闭包

node.js的模块实现,大致代码

首先准备一个nodejs规范的代码:
hello.js

var s = 'Hello';
var name = 'world';console.log(s + ' ' + name + '!');

Node.js加载了hello.js后,它把这段代码包装一下,大概变成这样:

var module = {id: 'hello',exports: {}
};
var load = function () {// 实际我们自己编写的hello.js代码:function greet(name) {console.log('Hello, ' + name + '!');}module.exports = greet;// hello.js代码结束return module.exports;
};
var exports = load();
// 保存module:
save(module, exports);

module是nodejs自动加的一个对象,可见,初始化的时候会先对module.exports赋值一个空的对象{}。

save(module, exports);这个函数是个真·全局函数,作用是把exports这个变量存到某个全局变量中。其它模块通过require()函数实际上就是去这个全局变量里把对应的值拿出来。

这样,看js代码大概就明白了,为什么在nodejs里可以直接用module.exports和exports这两个语法。

module.exports和exports

module.exports和exports实际上都是对一个对象的引用,这个对象初始化就是一个空对象{}。所以直接就可以使用类似

示例一:
module.exports.foo = function () { return 'foo'; };
module.exports.bar = function () { return 'bar'; };
或者示例二:
exports.foo = function () { return 'foo'; };
exports.bar = function () { return 'bar'; };

这两个示例作用是一样的,其本质都是往最开始初始化的空数组里添加成员。

示例三
module.exports = {hello: hello,greet: greet
};

示例三就不一样了,实际上module.exports重新引用到了一个新的对象里。如果示例三前面有示例一或者二的代码,那么会最终导致示例一或者二导出的模块丢掉。

示例四
exports = {hello: hello,greet: greet
};

示例四看上去虽然和示例三差不多,但是这种写法实际上并没有输出任何变量!注意看nodejs的实现代码,load()函数里最后return的是module.exports,也就是说最后save的是module.exports的引用对象,而示例四中exports被赋值了一个新的对象,此时module.exports和exports引用的已经不是同一个对象了!

那么提问:示例三虽然对module.exports重新引用到了一个新的对象,最终结果也能实现模块的正常导出,那么示例三里的exports此时引用的是什么对象呢?

最后,如果你打算导出一个数组或者变量,或者函数,都会涉及到module.exports原引用对象的丢弃,要额外注意,此时要小心不要丢掉前面已经导出的模块。

结论

如果要输出一个键值对象{},可以利用exports这个已存在的空对象{},并继续在上面添加新的键值;

如果要输出一个函数或数组,必须直接对module.exports对象赋值。

所以我们可以得出结论:直接对module.exports赋值,可以应对任何情况:

module.exports = {foo: function () { return 'foo'; }
};
或者:
module.exports = function () { return 'foo'; };

最终,我们强烈建议使用module.exports = xxx的方式来输出模块变量,这样,你只需要记忆一种方法。

或者使用我喜欢的方法,对空对象直接添加值:

var foo = function () { return 'foo'; };...module.exports.foo = foo;//
module.exports.bar = function () { return 'bar'; };

参考

liaoxuefeng

exports 和 module.exports 的区别

w3cschool

JS是按值传递还是按引用传递?,但是我不是很同意文中所说的按共享传递这名字的叫法。实际上无论传递普通变量还是传递函数,都是按值拷贝传递,只不过传递对象的时候,拷贝过去的是个引用变量罢了,即引用副本。
这里就是c语言指针的思想。

如果你对我上面所讲的还不明白,建议去把c语言里的指针好好的重学一遍。真正理解透彻了c里面的指针,学起来其它所有语言都不怕。

转载于:https://www.cnblogs.com/acbingo/p/7709363.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/454305.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

c语言贪吃蛇最简单代码_C语言指针,这可能是史上最干最全的讲解啦(附代码)!!!...

点击上方“大鱼机器人”,选择“置顶/星标公众号”福利干货,第一时间送达!指针对于C来说太重要。然而,想要全面理解指针,除了要对C语言有熟练的掌握外,还要有计算机硬件以及操作系统等方方面面的基本知识。所…

SpringSecurity深度解析与实践(3)

这里写自定义目录标题 引言SpringSecurity之授权授权介绍java权限集成 登录失败三次用户上锁 引言 SpringSecurity深度解析与实践(2)的网址 SpringSecurity之授权 授权介绍 Spring Security 中的授权分为两种类型: 基于角色的授权&#…

简单解释什么是 依赖注入 和 控制反转

简单解释什么是 依赖注入 和 控制反转2017-07-09 关于 依赖注入 与 控制反转 的概念有些人觉得很难理解,最近在给别人讲这个概念的时候梳理了一个比较好理解的解释,而且我认为非技术人员也应该能听的懂,因此分享给大家,希望下次你…

python pip install指定国内源镜像

有时候安装一些依赖包,网不好,直接超时,或者这个包就是死都下不下来的时候,可以指定国内源镜像。 pip install -i 国内镜像地址 包名 清华:https://pypi.tuna.tsinghua.edu.cn/simple 阿里云:http://mirr…

机器学习之单标签多分类及多标签多分类

单标签二分类算法 Logistic算法 单标签多分类算法 Softmax算法 One-Versus-One(ovo):一对一 One-Versus-All / One-Versus-the-Rest(ova/ovr): 一对多 ovo和ovr的区别 Error Correcting Output code…

ionic3 隐藏子页面tabs

看了几天ionic3 问题还挺多的,今天想把所有子页面tabs 给去掉,整了半天,发现app.Module 是可以配置的 修改 IonicModule.forRoot(MyApp) imports: [BrowserModule,// IonicModule.forRoot(MyApp),HttpModule,IonicModule.forRoot(…

cas单点登录-jdbc认证(三)

前言 本节的内容为JDBC认证,查找数据库进行验证,其中包括: 密码加密策略(无密码,简单加密,加盐处理)认证策略(jdbc)一、业务需求 不同的公司,需求业务需求或者…

get clone 出现 fatal: the remote end hung up unexpectedly5 MiB | 892.00 KiB/s 报错信息

fatal: the remote end hung up unexpectedly5 MiB | 892.00 KiB/s 解决方案 (亲测有效) 解决方案如下: git clone时加上 --depth1,比如: git clone https://gitee.com/songyitian/tctm.git --depth 1depth用于指定…

mybatis foreach map_重学Mybatis(六)-------输入映射(含面试题)

博主将会针对Java面试题写一组文章,包括J2ee,SQL,主流Web框架,中间件等面试过程中面试官经常问的问题,欢迎大家关注。一起学习,一起成长,文章底部有面试题。入参映射关键字说明图中paramenterTy…

php输出多余的空格或者空行

1&#xff0c;文件是否有bom。可以通过脚步检测&#xff0c;或者利用notepa打开&#xff0c;查看编码格式。 2. <?php echo something; ?> 或许是你的php标签外&#xff0c;有空格或者空行。一般的项目都是用框架&#xff0c;包含很多的文件&#xff0c;如果一个个文…

执行git命令时出现fatal: ‘origin‘ does not appear to be a git repository错误

执行git命令时出现fatal: ‘origin’ does not appear to be a git repository错误 在执行git pull origin master时出现&#xff1a;   fatal: ‘origin’ does not appear to be a git repository   致命提示:“origin”看起来不是一个git存储库   fatal: Could not r…

蒋涛作序盛赞Leo新作为“程序员职场实用百科全书”——《程序员羊皮卷》连载(1)

《程序员羊皮卷》当当购买地址&#xff1a;http://product.dangdang.com/product.aspx?product_id20691986 互动购买地址&#xff1a;http://www.china-pub.com/196049 程序员行业从外面看起来有很多绚丽的光环&#xff0c;这里有无数以程序致富的天才&#xff0c;世界首富比…

matlab ones函数_Matlab中相见恨晚的命令(持续更新)

知乎上有个“有哪些让人相见恨晚的Matlab命令”的话题&#xff0c;很多答主提供的命令确实很实用&#xff0c;为了更方便大家的学习&#xff0c;我就知乎上的答案和我自己想到的都综合整理成了一篇文章&#xff0c;把我觉得很实用的指令整理出来。知乎原答案链接dbstop if erro…

机器学习之特征工程

特征工程-概念 特征工程是一个面向十分广的概念&#xff0c;只要是在处理数据就可以认为是在做特征工程。个人理解&#xff0c;真正意义上的特征工程还是数据降维和数据升维的过程。 而前期对数据的处理过程&#xff1a; 需要哪些数据&#xff1f;数据如何存储&#xff1f;数…

ArcGIS AO开发高亮显示某些要素

参考代码1 ifeaturecursor pcur ifeatureclass.search(iqueryfilter pfilter); pfilter.whereclause strAddress; //输入查询条件&#xff0c;也就是你寸地址的字段名didian ifeature pfeat pcur.nextfeature();// 如果pCur多个要素&#xff0c;则可以考虑将其合并并一起高亮…

Oracle传输表空间介绍

传输表空间通过拷贝数据文件的方式&#xff0c;实现可跨平台的数据迁移&#xff0c;效率远超expdp/impdp, exp/imp等工具。还可以应用跨平台&数据库版本迁移表数据、归档历史数据和实现表空间级时间点数据恢复等场景。转载于:https://www.cnblogs.com/ilifeilong/p/7712654…

git push到GitHub的时候遇到! [rejected] master -> master (non-fast-forward)的问题

git push到GitHub的时候遇到! [rejected] master -> master (non-fast-forward)的问题 解决方法&#xff1a; 1、git pull origin master --allow-unrelated-histories //把远程仓库和本地同步&#xff0c;消除差异 2、重新add和commit相应文件 3、git push origin maste…

程序员考核的五大死因(上)

程序员作为企业开发力量的最核心资产&#xff0c;无疑得到公司从上至下的一致关注。开发是个智力密集型产业&#xff0c;程序开发的特点是&#xff0c;付出相同时间的情况下&#xff0c;两个开发者之间的产能会相差十几甚至几十倍。软件开发人员向来以“不容易考核、工作不容易…

du -sh 如何找到最大的文件夹_小白必看!手把手教你如何在linux上安装redis数据库...

首先我们要清楚redis是什么&#xff1f;redis是一种非关系型数据库&#xff0c;它与MySQL的这种关系型数据库不同&#xff0c;MySQL是将数据存储在磁盘中&#xff0c;而redis是储存在内存中。一般很多公司都是使用MySQLredis两种数据存储方式&#xff0c;这样可以提高性能&…

Linux删除特殊字符文件

1.删除带“-”的文件名的方法使用-- &#xff08;2个横杠&#xff09;#touch -- -%F-%T#rm -- -%F-%Trm: remove regular empty file -%F-%T?使用绝对路径并TAB特殊文件名#rm /root/-%F-%Trm: remove regular empty file /root/-%F-%T?2. 删除包含其它特殊字符的文件对于含有…