nodejs中exports与module.exports的实践
只要是在nodejs中写自己的文件模块就少不了会遇到module.exports和exports的使用,看别人的代码大多都会使用“module.exports=exports=<对象/函数等>”怪异的串联用法,一问原因,貌似都是云里雾里,如此写法更像是保守的防止性写法。
这种问题除了看源代码外,只能写点代码进行求证。
写了两个模块文件,provider.js产生任意类型的对象, customer.js返回并输出provider对象。
第一种情况:
provider.js,直接在exports上设置任意类型的对象。
exports = {name:'kxh'}
/*exports = function(){
console.log('kxh');
};
exports = 'kxh';*/ console.log('*******provider-module***********');
console.log(module);
console.log('*******provider-exports***********');
console.log(exports);
customer.js
var p = require('./provider'); console.log('*******customer-result***********');
console.log(p);
执行customer.js结果:
*******provider-module***********
{ id: 'D:\\ProgramDemos\\Web\\nodejs\\TestNode\\provider.js',
exports: {},
parent:
{ id: '.',
exports: {},
parent: null,
filename: 'D:\\ProgramDemos\\Web\\nodejs\\TestNode\\customer.js',
loaded: false,
children: [ [Circular] ],
paths:
[ 'D:\\ProgramDemos\\Web\\nodejs\\TestNode\\node_modules',
'D:\\ProgramDemos\\Web\\nodejs\\node_modules',
'D:\\ProgramDemos\\Web\\node_modules',
'D:\\ProgramDemos\\node_modules',
'D:\\node_modules' ] },
filename: 'D:\\ProgramDemos\\Web\\nodejs\\TestNode\\provider.js',
loaded: false,
children: [],
paths:
[ 'D:\\ProgramDemos\\Web\\nodejs\\TestNode\\node_modules',
'D:\\ProgramDemos\\Web\\nodejs\\node_modules',
'D:\\ProgramDemos\\Web\\node_modules',
'D:\\ProgramDemos\\node_modules',
'D:\\node_modules' ] }
*******provider-exports***********
{ name: 'kxh' }
*******customer-result***********
{}
从结果看,直接向exports上设置任意类型的对象都不会被require返回给调用模块。require返回的是module.exports的空对象。
第二种情况:
provider.js,为exports设置任意类型的属性。
exports.name = {firstName:'xh', lastName:'k'};
//exports.name = "kxh";
/*exports.printName = function(){
console.log("kxh");
};*/ console.log('*******provider-module***********');
console.log(module);
console.log('*******provider-exports***********');
console.log(exports);
customer.js不变。
执行customer.js结果:
*******provider-module***********
{ id: 'D:\\ProgramDemos\\Web\\nodejs\\TestNode\\provider.js',
exports: { name: { firstName: 'xh', lastName: 'k' } },
parent:
{ id: '.',
exports: {},
parent: null,
filename: 'D:\\ProgramDemos\\Web\\nodejs\\TestNode\\customer.js',
loaded: false,
children: [ [Circular] ],
paths:
[ 'D:\\ProgramDemos\\Web\\nodejs\\TestNode\\node_modules',
'D:\\ProgramDemos\\Web\\nodejs\\node_modules',
'D:\\ProgramDemos\\Web\\node_modules',
'D:\\ProgramDemos\\node_modules',
'D:\\node_modules' ] },
filename: 'D:\\ProgramDemos\\Web\\nodejs\\TestNode\\provider.js',
loaded: false,
children: [],
paths:
[ 'D:\\ProgramDemos\\Web\\nodejs\\TestNode\\node_modules',
'D:\\ProgramDemos\\Web\\nodejs\\node_modules',
'D:\\ProgramDemos\\Web\\node_modules',
'D:\\ProgramDemos\\node_modules',
'D:\\node_modules' ] }
*******provider-exports***********
{ name: { firstName: 'xh', lastName: 'k' } }
*******customer-result***********
{ name: { firstName: 'xh', lastName: 'k' } }
从结果看,为exports设置任意类型的属性,module.exports保持同步,能被require返回出去。
第三种情况:
provider.js,为exports设置任意类型的属性,并且为module.exports设置同名的或不同名的任意类型的属性。
exports.name = {firstName:'xh', lastName:'k'};
//exports.name = "kxh";
/*exports.printName = function(){
console.log("kxh");
};*/
//module.exports.name = {firstName:'wf', lastName:'z'};
module.exports.mail = "kxh@kxh.com"; console.log('*******provider-module***********');
console.log(module);
console.log('*******provider-exports***********');
console.log(exports);
customer.js不变。
执行customer.js结果:
*******provider-module***********
{ id: 'D:\\ProgramDemos\\Web\\nodejs\\TestNode\\provider.js',
exports:
{ name: { firstName: 'xh', lastName: 'k' },
mail: 'kxh@kxh.com' },
parent:
{ id: '.',
exports: {},
parent: null,
filename: 'D:\\ProgramDemos\\Web\\nodejs\\TestNode\\customer.js',
loaded: false,
children: [ [Circular] ],
paths:
[ 'D:\\ProgramDemos\\Web\\nodejs\\TestNode\\node_modules',
'D:\\ProgramDemos\\Web\\nodejs\\node_modules',
'D:\\ProgramDemos\\Web\\node_modules',
'D:\\ProgramDemos\\node_modules',
'D:\\node_modules' ] },
filename: 'D:\\ProgramDemos\\Web\\nodejs\\TestNode\\provider.js',
loaded: false,
children: [],
paths:
[ 'D:\\ProgramDemos\\Web\\nodejs\\TestNode\\node_modules',
'D:\\ProgramDemos\\Web\\nodejs\\node_modules',
'D:\\ProgramDemos\\Web\\node_modules',
'D:\\ProgramDemos\\node_modules',
'D:\\node_modules' ] }
*******provider-exports***********
{ name: { firstName: 'xh', lastName: 'k' },
mail: 'kxh@kxh.com' }
*******customer-result***********
{ name: { firstName: 'xh', lastName: 'k' },
mail: 'kxh@kxh.com' }
从结果看,如果设置不同名的属性,则为合并到module.exports并返回,如果是同名属性则require返回的全是module.exports。
第四种情况:
provider.js,不论为exports设置社么样类型的属性,直接为module.exports设置了任意类型对象。
exports.name = {firstName:'xh', lastName:'k'};
//exports.name = "kxh";
/*exports.printName = function(){
console.log("kxh");
};*/ //module.exports = {name:'kxh'};
module.exports = function(){
console.log('kxh');
}; console.log('*******provider-module***********');
console.log(module);
console.log('*******provider-exports***********');
console.log(exports);
customer.js不变。
执行customer.js结果:
*******provider-module***********
{ id: 'D:\\ProgramDemos\\Web\\nodejs\\TestNode\\provider.js',
exports: [Function],
parent:
{ id: '.',
exports: {},
parent: null,
filename: 'D:\\ProgramDemos\\Web\\nodejs\\TestNode\\customer.js',
loaded: false,
children: [ [Circular] ],
paths:
[ 'D:\\ProgramDemos\\Web\\nodejs\\TestNode\\node_modules',
'D:\\ProgramDemos\\Web\\nodejs\\node_modules',
'D:\\ProgramDemos\\Web\\node_modules',
'D:\\ProgramDemos\\node_modules',
'D:\\node_modules' ] },
filename: 'D:\\ProgramDemos\\Web\\nodejs\\TestNode\\provider.js',
loaded: false,
children: [],
paths:
[ 'D:\\ProgramDemos\\Web\\nodejs\\TestNode\\node_modules',
'D:\\ProgramDemos\\Web\\nodejs\\node_modules',
'D:\\ProgramDemos\\Web\\node_modules',
'D:\\ProgramDemos\\node_modules',
'D:\\node_modules' ] }
*******provider-exports***********
{ name: { firstName: 'xh', lastName: 'k' } }
*******customer-result***********
[Function]
从结果看,不论为exports设置社么样类型的属性,直接为module.exports设置了任意类型对象,则require一律返回module.exports。
从上面的四种实践结果来看:
require返回的是module.exports,在module.exports上可以设置函数、对象实例、基本类型的变量等,因此,一般就是module.exports作为模块的到处就行了。
如果想用exports作为模块的返回,那么就为它设置一个属性,并且不要在module.exports上设置同名的属性。
end
^-^
nodejs中exports与module.exports的实践的更多相关文章
- nodejs模块中exports和module.exports的区别
通过Node.js的官方API可以看到Node.js本身提供了很多核心模块 http://nodejs.org/api/ ,这些核心模块被编译成二进制文件,可以require('模块名')去获取:核心 ...
- nodejs中exports与module.exports的区别详细介绍
如果模块是一个特定的类型就用Module.exports.如果模块是一个典型的"实例化对象"就用exports. exports.name = function() { conso ...
- nodejs中的exports和module.exports
module是随文件而生的全局变量,它有exports属性,这个属性默认是一个空的字典. node的设计者画蛇添足有定义了一个exports全局变量,export指向module.exports所指向 ...
- 通过Anuglar Material串串学客户端开发 - NodeJS模块机制之Module.Exports
module.exports 前文讲到在Angular Material的第二个编译文件docs/gulpfile.js中却看到了一个奇怪的东西module.exports那么module.expor ...
- nodeJS实战:自定义模块与引入,不同模块的函数传递及回调处理,exports与module.exports(基于nodejs6.2.0)
前言:本文基于上一篇文章中的源代码进行改写,地址:http://blog.csdn.net/eguid_1/article/details/52182386 注意:为什么不用module.export ...
- Node.js中exports,module.exports以及require方法
在Node.js中,使用module.exports.f = ...与使用exports.f = ...是一样的,此时exports就是module.exports的一种简写方式.但是,需要注意的是, ...
- nodeJS学习(9)--- nodeJS模块:exports vs module.exports
模块简介: 通过Node.js的官方API可以看到Node.js本身提供了很多核心模块 http://nodejs.org/api/ 这些核心模块被编译成二进制文件,可以 require('模块名') ...
- Node.js中exports与module.exports的区别
原文:http://www.hacksparrow.com/node-js-exports-vs-module-exports.html 你肯定对Node.js模块中用来创建函数的exports对象很 ...
- Node.js中的exports与module.exports的区分
1. module应该是require方法中,上下文中的对象 2. exports对象应该是上下文中引用module.exports的新对象 3. exports.a = xxx 会将修改更新到mod ...
- 【nodejs】exports 和 module.exports 的区别
require 用来加载代码,而 exports 和 module.exports 则用来导出代码.但很多新手可能会迷惑于 exports 和 module.exports 的区别,为了更好的理解 e ...
随机推荐
- 谈谈final的作用
前言 一直想写写这个话题.代表公司也面试过一些求职者,每次面试我必问的两个问题之一就是“请你谈一谈对于final关键字的理解”.这是一个简单的小问题,但是不要小看它,通过对这个问题的回答以及一些简单的 ...
- 人人都是 DBA(X)资源信息收集脚本汇编
什么?有个 SQL 执行了 8 秒! 哪里出了问题?臣妾不知道啊,得找 DBA 啊. DBA 人呢?离职了!!擦!!! 程序员在无处寻求帮助时,就得想办法自救,努力让自己变成 "伪 DBA& ...
- Alpha阶段冲刺总结
Alpha阶段冲刺阶段总结 预期计划: 本阶段的预期计划是实现打地鼠游戏的基本功能,包括:游戏功能.难度调节功能.计时功能.计数记分功能.DIY设置功能.分数记录功能. 实际进展: 在经过三周的Alp ...
- Etag缓存在PHP和NodeJS中的实现
HTTP 提供了许多页面缓存的方案,其中属 Etag 和 Last-Modified 应用最广.本文会先介绍 Etag 的应用场景,然后说说他在 php 和 node 中的使用. 本文地址:http: ...
- 利用avalon 实现一个简单的成绩单
本文的灵感是来自Halower的这篇博文,他是使用knockout与jQuery实现的.不过我觉得MVVM本来就强大的事件绑定功能,因此用jQuery 是多此一举.另,他也用了一些面向对象的写法.我个 ...
- python Web开发框架-Django (1)
以前用web.py(另外一款轻量级web开发框架)做一个监控管理平台,没有做特别的记录就不好拾起来.最近做一个日志聚合系统,使用的是django,这次就记下来,方便查询. Django是一个高效的we ...
- Android中viewPager的一两点使用
Android中viewPager的一两点使用 viewPager是谷歌官方提供的一种方便实现页面滑动效果的控件,可以直接使用也可以和fragment联合使用.这里只简单说下直接使用. 使用viewP ...
- Redis中统计各种数据大小的方法
转载于:http://www.itxuexiwang.com/a/shujukujishu/redis/2016/0216/125.html?1455853369如果 MySQL 数据库比较大的话,我 ...
- 更新日志 - fir.im 新版优化上线
经过这段时间的用户反馈收集和新版本的功能调研,我们对 fir.im Rio 上传下载.应用管理再次做了调整优化.感谢之前内测用户的反馈与建议.目前 fir.im Rio 新版已正式上线,主要优化有以下 ...
- IOS笔记045-UIDatePicker和UIPickerView
这是两种可以上下滚动的控件. 这是UIDatePicker,可以显示日期和时间. 这个是UIPickerView,显示类似几个选择项的界面. 注意点:PickerView的高度不能改,默认162,Pi ...