最近看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.jsmodule.exports.name = 'amy'//b.jsvar a = require('./b.js')console.log(a) // 输入: { name: 'amy' }
应用exports属性的形式导出:
//a.jsexports.name = 'amy'//b.jsvar a = require('./b.js')console.log(a) // 输入: { name: 'amy' }
应用exports间接赋值的形式导出:
//a.jsexports = { name: 'amy' }//b.jsvar 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
导入。