node.js模块中exports和module.exports的区别

Node应用由模块组成,采用CommonJS模块规范。javascript

根据这个规范,每一个文件就是一个模块,有本身的做用域。在一个文件里面定义的变量、函数、类,都是私有的,对其余文件不可见。java

CommonJS规范规定,每一个模块内部,module变量表明当前模块。这个变量是一个对象,它的exports属性(即module.exports)是对外的接口。加载某个模块,实际上是加载该模块的module.exports属性。app

var x = 5; var addX = function (value) { return value + x; }; module.exports.x = x; module.exports.addX = addX;

上面代码经过module.exports输出变量x和函数addX。函数

require方法用于加载模块。工具

var example = require('./example.js'); console.log(example.x); // 5 console.log(example.addX(1)); // 6

加载:require

语法:ui

var 自定义变量名称 = require('模块')

做用:spa

一、执行被加载模块中的代码code

二、获得被加载模块中的exports导出接口对象对象

导出:exports

Node中是模块做用域,默认文件中全部的成员只在当前文件模块有效。接口

对于但愿能够被其它模块访问的成员,咱们就须要把这些公开的成员都挂载到exports接口对象中就能够了。

1. 导出多个成员(必须在对象中)

//foo.js var foo = 'bar' function add(x, y) { return x + y } exports.foo = foo exports.a = "科比" exports.b= "詹姆斯" exports.c = add //main.js var fooExports = require('./foo') console.log(fooExports) //结果 { foo: 'bar', a: '科比', b: '詹姆斯', c: [Function: add] }

2. 导出单个成员

错误写法1

//foo.js var foo = 'bar' function add(x, y) { return x + y } exports = foo exports.a = "科比" exports.b= "詹姆斯" exports.c = add //main.js var fooExports = require('./foo') console.log(fooExports) 结果为空对象 {}

错误写法2

//foo.js var foo = 'bar' function add(x, y) { return x + y } exports.a = "科比" exports.b= "詹姆斯" exports.c = add exports = foo //main.js var fooExports = require('./foo') console.log(fooExports) 结果为{ a: '科比', b: '詹姆斯', c: [Function: add] }

若是一个模块须要直接导出某个成员,而非挂载的方式,那这个时候必须使用下面这种方式

//foo.js var foo = 'bar' function add(x, y) { return x + y } module.exports = foo //位置一 exports.a = "科比" exports.b= "詹姆斯" exports.c = add //module.exports = foo 位置二 /* module.exports = { 位置三 add: function () { return x + y }, str: 'hello' } */ //main.js var fooExports = require('./foo') console.log(fooExports)

结果:

只有一个module.exports时,无论是在位置一仍是位置二,都为 bar。

当有两个module.exports 时,好比一个在位置一,另外一个在位置三,会导出位置三的对象(module.exports会被后者覆盖)。

上面的结果出现的缘由:exports 和module.exports是有区别的。

在Node中,每一个模块内部都有一个本身的module 对象,该 module 对象中,有一个成员叫exports也是一个对象,相似这样:

var module = { exports: { foo: 'bar', add: function } }

每次导出的对象是module.exports,若是你须要对外导出成员,只须要把导出的成员挂载到module.exports中。

也就是说module.exports才是真正的接口,exports只不过是它的一个辅助工具。最终返回给调用的是module.exports而不是exports。

为了方便,Node为每一个模块提供一个exports变量,指向module.exports。这等同在每一个模块头部,有一行这样的命令:

var exports = module.exports

exports至关因而 一个引用,指向module.exports对象,因此有

console.log(module.exports === exports) ///true 

因而咱们能够直接在 exports 对象上添加方法,表示对外输出的接口,如同在module.exports上添加同样。注意,不能直接将exports变量指向一个值,由于这样等于切断了exports与module.exports的联系。

同理,给 module.exports 从新赋值也会断开。

可是这里又从新创建二者的引用关系:

exports = module.exports

最后,必定要记得return的是module.exports

若是给exports赋值,断开了两个引用之间的联系,就无论用了。

module.exports.foo = 'bar' exports.a = 'abc' exports = {} exports.b = '123' //断开链接后,就没联系了,需从新联系起来 exports = module.exports exports.foo = 'haha' module.exports.a = 'cba' 结果 { foo: 'haha', a: 'cba' }

exports 和 module.exports 的使用

若是要对外暴露属性或方法,就用 exports 就行,要暴露对象(相似class,包含了不少属性和方法),就用 module.exports。

相关文章
相关标签/搜索