1、nodeJS采用commonJs规范,当前文件是一个模块(module)私有域,通过exports属性导出,通过require()引入模块,通过.xx去获取值,从而了解到加载某个模块,其实是加载该模块的exports属性。
2、exports是module.exports的别名,不要在同一个文件内同时使用两个,否则只能获取到module.exports的值.
简单来说如下:
exports = module.exports = {};
module
module是一个对象 {Object}
console.log(module);
然后在终端打开就能看到module其实是一个Module实例,你可以这么理解,NodeJS中定义了一个Module类,这个类中有很多属性和方法
Module {
id: '.',
path:,
exports: {},
parent: null,
filename: ,
loaded: false,
children: [],
paths: []
}
exports是其中的一个属性.
当每个js文件在执行或被require的时候,NodeJS其实创建了一个新的实例var module = new Module(),这个实例名叫module。
这也就是为什么你并没有定义module这个变量,却能console.log出来而不会报错的原因。
module.exports
console.log(module);// exports: {}
module.exports = {
demo : () => {
console.log(123);
}
}
console.log(module);//exports: { demo: [Function: demo] }
简单来说就是 给Module实例中的exports对象中添加方法/属性。
exports
console.log(exports)//{}
console.log(module)//{}
exports.demo = () => {
console.log(123);
}
exports.a = "ccc"
console.log(module);//exports: { demo: [Function (anonymous)], a: 'ccc' }
console.log(exports);//{ demo: [Function (anonymous)] , a: 'ccc'}
可以说是exports其实是module.exports的引用,你可以这么理解,NodeJS在你的代码之前悄悄的加了以下代码:
var module = new Module();
var exports = module.exports;
这也就是为什么你并没有定义exports这个变量,却能console.log出来而不会报错的原因。
总结
module.exports和exports的区别就是var a={}; var b=a;,a和b的区别
改变exports的指向后所添加的exports.xxx都是无效的。因为require返回的只会是module.exports
不能在使用了exports.xxx之后,改变module.exports的指向。因为exports.xxx添加的属性和方法并不存在于module.exports所指向的新对象中。
对于要导出的属性,可以简单直接挂到exports对象上
对于类,为了直接使导出的内容作为类的构造器可以让调用者使用new操作符创建实例对象,应该把构造函数挂到module.exports对象上,不要和导出属性值混在一起