最近看 Node.js 的时候,看到有 exports 和module.exports两种导出模块的形式,非常好奇它们有什么区别,于是钻研了一番
Node
外面的模块零碎遵循的是 CommonJS
标准。
那问题又来了,什么是 CommonJS
标准呢?
CommonJS
定义的模块分为: 模块标识(module
)、模块定义(exports
)、模块援用(require
)
module和 exports 都是 Node.js 中的内置对象,咱们在控制台把它们输入来
console.log(exports)
// {}
console.log(module)
//Module {
// id: '.',
// path: 'F:\\node\\test',
// exports: {},
// ......
//}
能够看进去,exports是 module 中的一个属性,并且都是空对象{},实际上exports 是 module.exports 的一个援用,exports 指向的是 module.exports,它们指向同一个内存地址,也就是说不扭转它们内存指向的状况下,它们是等价的,即module.exports === exports
当初新建一个 a.js
用来导出模块,新建一个 b.js
用来导入模块
应用 module.exports 的形式导出:
//a.js
module.exports.name = 'amy'
//b.js
var a = require('./b.js')
console.log(a) // 输入: {name: 'amy'}
应用 exports 属性的形式导出:
//a.js
exports.name = 'amy'
//b.js
var a = require('./b.js')
console.log(a) // 输入: {name: 'amy'}
应用 exports 间接赋值的形式导出:
//a.js
exports = {name: 'amy'}
//b.js
var a = require('./b.js')
console.log(a) // 输入: {}
从输入后果能够看出,应用 module.exports 和 exports 属性两种导出形式是一样的,间接给 exports 赋值的导出形式是有效的
咱们再看《Node.js 疾速入门》第三章的一段话
在内部援用该模块时,其接口对象就是要输入的对象自身,而不是原先的 exports。
事实上,exports 自身仅仅是一个一般的空对象,即 {},它专门用来申明接口,本
质上是通过它为模块闭包①的外部建设了一个无限的拜访接口。因为它没有任何非凡的中央,
所以能够用其余货色来代替。不能够通过对 exports 间接赋值代替对 module.exports 赋值。exports 实际上只是一个和 module.exports 指向同一个对象的变量,它自身会在模块执行完结后开释,但 module 不会,因而只能通过指定module.exports 来扭转拜访接口。
总结
require
引入的对象实质上是 module.exports
,尽管应用exports
点属性的形式也能够导出,然而为了防止出错,尽量都用 module.exports
导出,而后用 require
导入。