最近在看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是模块中的一个属性,都是空对象{}。其实exports是对module.exports的引用,exports指向module.exports,指向同一个内存地址,也就是说,不改变它们的内存指针,它们是等价的,即module.exports===exports现在新建一个a.js用来导出模块,新建一个b.js用来导入模块使用模块Exportby.exports://a.jsmodule.exports.name='amy'//b.jsvara=require('./b.js')console.log(a)//输出:{name:'amy'}使用exports属性导出://a.jsexports.name='amy'//b.jsvara=require('./b.js')console.log(a)//output:{name:'amy'}使用exports直接导出://a.jsexports={name:'amy'}//b.jsvara=require('./b.js')console.log(a)//输出:{}从输出结果可以看出,使用module.exports和exports的两种导出方式属性是一样的,直接给exports赋值的export方法是无效的看第三章Node.js中的《Node.js开发指南》一段快速入门模块在被外部引用时,其接口对象是要导出的对象本身,而不是原始导出。其实exports本身只是一个普通的空对象,即{},专门用来声明接口,本质上是通过它为模块闭包①内部建立一个有限访问的接口。由于它没有什么特别之处,所以可以用其他东西代替。不可能直接分配给exports而不是分配给module.exports。exports其实只是一个指向和module.exports同一个对象的变量,在module执行完后会自己释放,而module不会,所以只能通过指定module.exports来改变访问接口。总结一下,require引入的对象本质上就是module.exports。虽然也可以使用导出点属性导出,但是为了避免出错,尽量使用module.exports导出,再使用require导入。
