(转)Node.js module.exports与exports
本文转自Node.js module.exports与exports
作者: chemdemo
折腾Node.js有些日子了,下面将陆陆续续记录下使用Node.js的一些细节。
熟悉Node.js的童鞋都知道,Node.js作为服务器端的javascript运行环境,它使用npm作为通用的包管理工具,npm遵循CommonJS规范定义了一套用于Node.js模块的约定,关于npm实现Node.js模块的更多细节请细读深入Node.js的模块机制,这里简单讲下书写Node.js代码时module.exports与exorts的区别。
在浏览器端js里面,为了解决各模块变量冲突等问题,往往借助于js的闭包把所有模块相关的代码都包装在一个匿名函数里。而Node.js编写模块相当的自由,开发者只需要关注require,exports,module等几个变量就足够,而为了保持模块的可读性,很推荐把不同功能的代码块都写成独立模块,减少各模块耦合。开发者可以在“全局”环境下任意使用var申明变量(不用写到闭包里了),通过exports暴露接口给调用者。
我们经常看到类似export.xxx = yyy或者module.exports = xx这样的代码,可实际在通过require函数引入模块时会出现报错的情况,这是什么原因导致的呢?
Node.js在模块编译的过程中会对模块进行包装,最终会返回类似下面的代码:
(function (exports, require, module, __filename, __dirname) {
// module code...
});
其中,module就是这个模块本身,require是对Node.js实现查找模块的模块Module._load实例的引用,__filename和__dirname是Node.js在查找该模块后找到的模块名称和模块绝对路径,这就是官方API里头这两个全局变量的来历。
关于module.exports与exorts的区别,了解了下面几点之后应该就完全明白:
模块内部大概是这样:
exports = module.exports = {};
- exports是module.exports的一个引用
- require引用模块后,返回给调用者的是module.exports而不是exports
- exports.xxx,相当于在导出对象上挂属性,该属性对调用模块直接可见
- exports =相当于给exports对象重新赋值,调用模块不能访问exports对象及其属性
- 如果此模块是一个类,就应该直接赋值module.exports,这样调用者就是一个类构造器,可以直接new实例
客官如果看明白咋回事儿了下面的内容可以忽略:)
假如有模块a.js代码如下:
exports.str = 'a';
exports.fn = function() {};
对a模块的调用:
var a = require('./a');
console.log(a.str);
console.log(a.fn());
这样用是对的,如果改造a如下:
exports.str = 'a';
exports = function fn() {};
在调用a模块时自然没用fn属性了。
再改造下a模块:
exports.str = 'a';
module.exports = function fn() {};
这时a模块其实就是fn函数的引用,也就是说可以require('./a')()这样使用,而同时不再有str属性了。
下面直接导出一个类:
module.exports = function A() {};
调用:
var A = require('./a');
var a = new A();
总结下,有两点:
- 对于要导出的属性,可以简单直接挂到exports对象上
- 对于类,为了直接使导出的内容作为类的构造器可以让调用者使用new操作符创建实例对象,应该把构造函数挂到module.exports对象上,不要和导出属性值混在一起
最后,不用再纠结module.exports与exorts什么时候该用哪个了吧~
(转)Node.js module.exports与exports的更多相关文章
- node.js module.exports & exports & module.export all in one
node.js module.exports & exports & module.export all in one cjs const log = console.log; log ...
- Node.js & module.exports & exports
Node.js & module.exports & exports https://www.cnblogs.com/xgqfrms/p/9493550.html exports &a ...
- 创建并发布node.js module
创建node.js module. 创建一个文件夹,用来存放module. Cd到新创建的文件夹,运行npm init,会提示输入package的信息. 可以按照这个视频的来输入.Test com ...
- Node.js & module system
Node.js & module system Node.js v10.9.0 Documentation https://nodejs.org/api/modules.html#module ...
- 如何發佈一個完整Node.js Module
本文會透過以下幾個段落,讓各位一步一步學習如何寫一個自已的Node.js Module並且發佈到npm package上 Node.js Module 結構 我們先建立一個 NodeModuleDem ...
- Node.js module.exports和exports的区别
require 用来加载代码,而 exports 和 module.exports 则用来导出代码,从接触node.js就不会它们两陌生,上代码: foo.js exports.a = functio ...
- [ 转]Node.js模块 require和 exports
什么是模块? node.js通过实现CommonJS的Modules/1.0标准引入了模块(module)概念,模块是Node.js的基本组成部分.一个node.js文件就是一个模块,也就是说文件和模 ...
- node.js module初步理解
在开发一个复杂的应用程序的时候,我们需要把各个功能拆分.封装到不同的文件,在需要的时候引用该文件.没人会写一个几万行代码的文件,这样在可读性.复用性和维护性上都很差,几乎所有的编程语言都有自己的模块组 ...
- node.js module初步理解-(转载)
在开发一个复杂的应用程序的时候,我们需要把各个功能拆分.封装到不同的文件,在需要的时候引用该文件.没人会写一个几万行代码的文件,这样在可读性.复用性和维护性上都很差,几乎所有的编程语言都有自己的模块组 ...
随机推荐
- Linux内核及分析 第四周 扒开系统调用的三层皮(上)
实验过程 选择20号系统调用getpid(取得进程识别码) 在网上查询getpid函数的C语言代码以及其嵌入式汇编语句 C语言代码: #include <stdio.h> #include ...
- HelloWorld.php
没有写博的习惯,从今天开始.近期学习了下php,分享下我的第一个PHP. 工具:Hbuider+Wampserver 利用Wampserver就可以完成PHP脚本的编写和运行,本人之所以选择安装HBu ...
- 用户模拟+spec
用户模拟:用户模拟的对象分别为小学二年级学生,学生父亲以及小学教师. 名字 孔小颖 性别 男 职业 小学生 收入 来自父母给予 知识层次和能力 小学二年级 生活/工作情况 在学校上课,数学成绩较差,放 ...
- 业务-----部门Service常用逻辑
1.org实体类 public class Org implements Serializable { private static final long serialVersionUID = 1L; ...
- Trouble shooting(问题解决):centos 7 gnome show someting has gone wrong.
centos 7 升级 内核 3.10,startx启动不了了.进界面也是oh,no!someting has gone wrong . 参见帖子:http://bbs.csdn.net/topics ...
- [转帖] select、poll、epoll之间的区别总结[整理] + 知乎大神解答 https://blog.csdn.net/qq546770908/article/details/53082870 不过图都裂了.
select.poll.epoll之间的区别总结[整理] + 知乎大神解答 2016年11月08日 15:37:15 阅读数:2569 http://www.cnblogs.com/Anker/p/3 ...
- hive视图
简化复杂的查询 员工好.姓名.月薪.年薪.在一个emp表中; 部门名称在dept的表中;并未年薪起了一个名字annlsal 查询视图 视图是一个虚表,是不存数据的
- jq 事件取消绑定与重新绑定
前端有时会碰到这样的需求: 点击某个元素发送ajax请求, 发送期间此元素的鼠标相关事件(比如点击)无效, 发送完成鼠标点击事件功能恢复, 对于这种需求, 我们会遇到两种情况, 一种是点击的按钮为fo ...
- codeforces659B
Qualifying Contest CodeForces - 659B Very soon Berland will hold a School Team Programming Olympiad. ...
- BZOJ4516 SDOI2016生成魔咒(后缀数组+平衡树)
一个字符串本质不同的子串数量显然是总子串数减去所有height值.如果一个个往里加字符的话,每次都会改动所有后缀完全没法做.但发现如果从后往前加的话,每次只会添加一个后缀.于是我们把字符串倒过来,每次 ...