node.js中module.export与export的区别。
对module.exports和exports的一些理解
可能是有史以来最简单通俗易懂的有关Module.exports和exports区别的文章了。
exports = module.exports = {};
所以module.exports
和exports
的区别就是var a={}; var b=a;
,a和b的区别
看起来木有什么太大区别,但实际用起来的时候却又有区别,这是为啥呢,请听我细细道来
关于Module.exports和exports有什么区别,网上一搜一大把,但是说的都太复杂了…
听说exports是Module.exports对象的一个引用(reference)^1,什么是引用?!…_(:з」∠)_
当然啦,如果要彻底理解这两个导出的区别,最好肯定是去看源码,看看都是怎么封装的,功力深厚的童鞋应该一看就懂了。不过,源码我也是看不懂的…(ಥ_ಥ)
但是最近感觉杂七杂八看了好多文章做了好多实验之后,像是打开了任督二脉,机智的我好像有点上道了…
module
首先要明确的一点,module是一个对象 {Object}
。
当你新建一个文件,比如mo.js,文件内容如下:
1 |
console.log(module); |
然后在CMD里执行这个文件node mo.js
,就能看到module其实是一个Module实例,你可以这么理解,NodeJS中定义了一个Module类,这个类中有很多属性和方法,exports是其中的一个属性:
1 |
function Module { |
当每个js文件在执行或被require的时候,NodeJS其实创建了一个新的实例var module = new Module()
,这个实例名叫module
。
这也就是为什么你并没有定义module
这个变量,却能console.log出来而不会报错的原因。
module.exports
假设我有一个JS文件内容如下:
console.log(module); //你会看到Module中的exports为空对象{}
module.exports = {
print : function(){console.log(12345)}
}
console.log(module); //你会看到Module中的exports对象已经有了print()方法
有了上面的基础,很容易理解module.export
其实是给Module实例中的exports对象中添加方法/属性。
exports
通常使用exports的时候,是这么用的:
exports.print = function(){console.log(12345)}
假设我有一个JS文件内容如下:
console.log(module); //你会看到Module中的exports为空对象{}
console.log(exports); //你会看到Module中的exports为空对象{}
module.exports = {
print : function(){console.log(12345)}
}
console.log(module); //你会看到Module中的exports对象有了print()方法
exports.name = '小白妹妹';
console.log(module); //你会看到Module中的exports对象不仅有了print()方法,还有了name属性
由此也能看出,传说中的exports
其实是module.exports
的引用,你可以这么理解,NodeJS在你的代码之前悄悄的加了以下代码:
var module = new Module();
var exports = module.exports;
这也就是为什么你并没有定义exports
这个变量,却能console.log出来而不会报错的原因。
require
当你从外部调用某个模块,require其实是在require什么?^2
require的时候NodeJS会到处去找有没有这个模块,如果有,return的就是module.exports里的东东。
DOs & DONTs
- √你可以这样:
module.exports.name = '小白妹妹';
exports.age = 10;
module.exports.print = function(){console.log(12345)};
如果只是使用
.
来添加属性和方法,module.exports
和exports
混用是完全可以的,这种情况下,感觉exports
就是给懒人用的…毕竟能少写几个7个字符呢! - √也可以这样:
module.exports = {
name = '小白妹妹';
};
exports.age = 10;
module.exports.print = function(){console.log(12345)};
- ×但不可以这样:
module.exports = {
name = '小白妹妹';
};
exports = {age:10}; // exports现在是{age:10}这个对象的引用,不再是module.exports的引用了
console.log(module); //你会看到Module的exports中只有name属性!!!
- ×也不可以这样:
exports.age = 10;
console.log(module); //你会看到Module的exports中多了age属性
module.exports = {
name = '小白妹妹';
};
console.log(module); //你会看到Module的exports中还是只有name属性!!!
总结
还是那一句话,
module.exports
和exports
的区别就是var a={}; var b=a;
,a和b的区别- 改变
exports
的指向后所添加的exports.xxx
都是无效的。因为require返回的只会是module.exports
- 改变
- 不能在使用了
exports.xxx
之后,改变module.exports
的指向。因为exports.xxx
添加的属性和方法并不存在于module.exports
所指向的新对象中。 - 对于要导出的属性,可以简单直接挂到
exports
对象上 - 对于类,为了直接使导出的内容作为类的构造器可以让调用者使用new操作符创建实例对象,应该把构造函数挂到
module.exports
对象上,不要和导出属性值混在一起
感觉自己说的还是挺清楚哒~
不管你清不清楚,我反正是清楚了。_(:з」∠)_
node.js中module.export与export的区别。的更多相关文章
- node.js中module模块的理解
node.js中使用CommonJS规范实现模块功能,一个单独的文件就是一个单独的模块.通过require方法实现模块间的依赖管理. 通过require加载模块,是同步操作. 加载流程如下: 1.找到 ...
- Node.js中module文件定义的top-level变量为何是私有的
在Node.js中,module文件里面使用var,const或者let定义的top-level变量为何是私有的,只能在这个模块文件中使用呢? 原因就是,在模块文件中的内容执行之前,node.js会降 ...
- Node.js中Process.nextTick()和setImmediate()的区别
一.Webstrom使用node.js IDE的问题 在区别这两个函数之前来说一下Webstrom使用node.js IDE的问题,在配置Node.js的IDE了,但setImmediate().re ...
- Node.js 中 process.cwd()与__dirname的区别
process.cwd() 是当前执行node命令时候的文件夹地址 --工作目录,保证了文件在不同的目录下执行时,路径始终不变 __dirname 是被执行的js 文件的地址 --文件所在目录 当前模 ...
- Node.js中exports,module.exports以及require方法
在Node.js中,使用module.exports.f = ...与使用exports.f = ...是一样的,此时exports就是module.exports的一种简写方式.但是,需要注意的是, ...
- Node.js 的module 系统
相较于原生的JavaScript,不同的JavaScript文件之间很难共享变量.有鉴于此,Node.js在JavaScript的基础上进行了扩充,引入了require,exports,module三 ...
- Node.js中环境变量process.env详解
Node.js中环境变量process.env详解process | Node.js API 文档http://nodejs.cn/api/process.html官方解释:process 对象是一个 ...
- 初步揭秘node.js中的事件
当你学习node.js的时候,Events是一个非常重要的需要理解的事情.非常多的Node对象触发事件,你能在文档API中找到很多例子.但是关于如何写自己的事件和监听,你可能还不太清楚.如果你不了解, ...
- node.js中的路由(url)初步
1.建立n4_root.js var http = require('http'); var url = require('url'); //这是node.js中自带的var router = req ...
随机推荐
- 微信公众平台"微信连Wi-Fi"功能来了 线下微信增粉利器
微信连Wi-Fi功能在第三方开发者和服务商已经有出现了,但有些成本相对会高些.近日微信公众平台新添了一个功能插件“微信连Wi-Fi”,已有微信认证过的公众号即可申请开通.赶紧去布局这个线下微信增粉利器 ...
- 利用session_set_save_handler()函数将session保存到MySQL数据库中
PHP保存session默认的是采用的文件的方式来保存的,这仅仅在文件的空间开销很小的windows上是可以采用的,但是如果我们采用uinx或者是liux上的文件系统的时候,这样的文件系统的文件空间开 ...
- linux各目录的作用
- bzoj1023: [SHOI2008]cactus仙人掌图
学习了一下圆方树. 圆方树是一种可以处理仙人掌的数据结构,具体见这里:http://immortalco.blog.uoj.ac/blog/1955 简单来讲它是这么做的:用tarjan找环,然后对每 ...
- springMVC配置Json
步骤1:将json包引入工程中,分别是:jackson-annotations-2.7.0.jar,jackson-core-2.7.0.jar,jackson-databind-2.7.0.jar ...
- VC++ 应用程序无法正常启动0xc0150002
使用VC++开发软件,编译后的程序打不开,弹出错误框: 使用Dpends Walker查看依赖项,没有什么异常. 然后,右键"计算机",选择"管理",打开计 ...
- SQL 创建随机时间的函数
set ANSI_NULLS ON set QUOTED_IDENTIFIER ON go ALTER function [dbo].[fn_Randtime] ( @begin_date datet ...
- Qt文件路径分隔符
QDir::toNativeSeparators()QDir::separator()
- Web负载均衡的几种实现方式
Web负载均衡的几种实现方式摘要:负载均衡(Load Balance)是集群技术(Cluster)的一种应用.负载均衡可以将工作任务分摊到多个处理单元,从而提高并发处理能力.目前最常见的负载均衡应用是 ...
- MySql增加字段、删除字段、修改字段名称、修改字段类型
1.增加一个字段 alter table user add COLUMN new1 VARCHAR(20) DEFAULT NULL; //增加一个字段,默认为空 alter table user a ...