只要是在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的实践的更多相关文章

  1. nodejs模块中exports和module.exports的区别

    通过Node.js的官方API可以看到Node.js本身提供了很多核心模块 http://nodejs.org/api/ ,这些核心模块被编译成二进制文件,可以require('模块名')去获取:核心 ...

  2. nodejs中exports与module.exports的区别详细介绍

    如果模块是一个特定的类型就用Module.exports.如果模块是一个典型的"实例化对象"就用exports. exports.name = function() { conso ...

  3. nodejs中的exports和module.exports

    module是随文件而生的全局变量,它有exports属性,这个属性默认是一个空的字典. node的设计者画蛇添足有定义了一个exports全局变量,export指向module.exports所指向 ...

  4. 通过Anuglar Material串串学客户端开发 - NodeJS模块机制之Module.Exports

    module.exports 前文讲到在Angular Material的第二个编译文件docs/gulpfile.js中却看到了一个奇怪的东西module.exports那么module.expor ...

  5. nodeJS实战:自定义模块与引入,不同模块的函数传递及回调处理,exports与module.exports(基于nodejs6.2.0)

    前言:本文基于上一篇文章中的源代码进行改写,地址:http://blog.csdn.net/eguid_1/article/details/52182386 注意:为什么不用module.export ...

  6. Node.js中exports,module.exports以及require方法

    在Node.js中,使用module.exports.f = ...与使用exports.f = ...是一样的,此时exports就是module.exports的一种简写方式.但是,需要注意的是, ...

  7. nodeJS学习(9)--- nodeJS模块:exports vs module.exports

    模块简介: 通过Node.js的官方API可以看到Node.js本身提供了很多核心模块 http://nodejs.org/api/ 这些核心模块被编译成二进制文件,可以 require('模块名') ...

  8. Node.js中exports与module.exports的区别

    原文:http://www.hacksparrow.com/node-js-exports-vs-module-exports.html 你肯定对Node.js模块中用来创建函数的exports对象很 ...

  9. Node.js中的exports与module.exports的区分

    1. module应该是require方法中,上下文中的对象 2. exports对象应该是上下文中引用module.exports的新对象 3. exports.a = xxx 会将修改更新到mod ...

  10. 【nodejs】exports 和 module.exports 的区别

    require 用来加载代码,而 exports 和 module.exports 则用来导出代码.但很多新手可能会迷惑于 exports 和 module.exports 的区别,为了更好的理解 e ...

随机推荐

  1. 【C语言学习】《C Primer Plus》第4章 字符串和格式化输入/输出

    学习总结 1.String str=”hello world!”;(Java),char[20]=” hello world!”;(C).其实Java字符串的实现,也是字符数组. 2.字符串的尾部都会 ...

  2. 通过分析iframe和无阻塞脚本关系能让我们更懂iframe

    在我上篇文章里,我提到一种使用iframe完成无阻塞脚本加载的方式,因为我对iframe的偏见很大,所以上篇文章里我没有展开讨论这个问题. 文章发表后有位网友问了我这样一个问题,下面是他问题的原文,如 ...

  3. 写js写傻了,明天研究一下异步

    在html某元素上绑定一个click事件,该事件是一个执行事件很长的函数,比如执行几十亿或几百亿次加法,那么在这个函数执行的过程中,其他元素绑定的事件,是如何触发的呢,异步触发还是同步,触发时是怎么执 ...

  4. Java-单例模式(singleton)-转载

    概念: java中单例模式是一种常见的设计模式,单例模式分三种:懒汉式单例.饿汉式单例.登记式单例三种. 单例模式有一下特点: 1.单例类只能有一个实例. 2.单例类必须自己自己创建自己的唯一实例. ...

  5. EF架构~二级域名中共享Session

    回到目录 对于一个有点规模的网站,都会有各个子网站,说是子网站,其实也都是独立的站点,一般通过二次域名来分开,如www.zzl.com,它可以有很多子网站,如image.zzl.com,file.zz ...

  6. 1121冬至!!!巩固HTML基础第一堂

    今天只是把以前的知识巩固了一下.温故而知新,说的一点没错: 又新明白了一种居中对齐方法: 水平居中:align left(左侧对齐),center(居中对齐) 垂直居中:ralign top(上对齐) ...

  7. [Java面试九]脚本语言知识总结.

    核心内容概述 1.JavaScript加强,涉及到ECMAScript语法.BOM对象.DOM对象以及事件. 2.Ajax传统编程. 3.jQuery框架,九种选择器为核心学习内容 4.JQuery ...

  8. Android TextView 常用技巧

    Android ListView 常用技巧 Android TextView 常用技巧 TextView在Android中实现文字说明等功能,基本的使用都很简单,那么除了基本展示文字的使用,我们还能够 ...

  9. easyui combotree下拉框多选赋值

    发现jquery.easyui.min.js 1.3.4版本的用setValues给多选下拉框赋值不成功,只能用1.3.1版本的 Html代码: <input id="ProductL ...

  10. ASPNET_WEBAPI快速学习02

    这部分内容的学习,已经放了大半年时间了,果断补充上,尽早将过去遗留的老技术坑都补上.首先将介绍服务幂等性的概念和相关解决方案,这部分也将是本文的理解难点,由于WebAPI是一种Restful风格服务的 ...