module.exports与exports与require
1.nodejs的模块
Node.js分为原生模块 第三方模块 自定义模块
- 原生模块:不需要加载也不需要指定地址也不用npm下载 常见的有:
global; process; timer; console; module; buffer
- 第三方模块:npm下载到node_moules,不需要指定地址
- 自定义模块:用require引用,需要指定地址
2.nodejs的遵循的规则
- nodejs的模块遵循CommonJs规范;模块是Node.js的重要组成部分,文件与模块一一对应,一个Node.js文件就是一个模块,拥有单独的作用域。普通方式定义的变量,函数,对象都属于该模块内.
2.CommonJs
-
在模块运行时,会自动生成一个 module 对象和一个 exports 对象,module 对象下也有一个 exports 对象;为了方便使用,exports指向module.exports,相当于在模块头部加入了exports=module.exports,在对外输出时,可以给exports对象添加s属性(不能直接赋值,因为会改变exports=module.exports)默认情况下,module.exports 与 exports 是空对象 即
exports=module.exports={}
;当module.exports与exports被赋值时,该模块就是带返回值的模块。 -
通过require加载模块,通过exports和module.exports来暴露模块内容
-
所有代码都运行在模块作用域,不会污染全局作用域,模块可以多次加载,但只会在第一次加载时运行一次,然后运行结果就被缓存,以后再加载,就直接读取缓存结果,模块的加载顺序,按照代码的出现顺序同步加载的
-
module.exports与exports的区别:
(1)exports只是module.exports的一个引用;
(2)一个模块真正导出的是module.exports,require引用的也是module.exports而非exports
(3)module.exports可以把类,方法,数组,对象,类公布给外部文件,module.exports可直接导出(直接赋值)
(4)exports只能以引用的方式把值,方法,数组,对象公布给外部文件,exports不可以直接导出
引用即[[exports指向的地址与module.exports指向的地址一致exports的值改变时,地址(重新开辟新的空间)就会改变]]let obj1={a:1};let obj2=obj1;console.log(obj1,obj2);//{a:1} {a:1}obj2.a=2;console.log(obj1,obj2);//{a:2} {a:2}obj2={b:2}; //开辟新的空间存储 obj2console.log(obj1,obj2);//{a:2} {b:2}obj2就是obj1的引用
所以node模块经常这样写: exports=module.exports=()=>{ } 这是为了让exports引用指向module.exports同一块内存,确保数据的一致性。
延伸export和export default
- export与export default可以用于导出常量,函数,文件,模块
- 在一个文件或模块中,export,import可以有多个,export default只能有一个
- 通过export方式导出 ,在导出时要加入{},export default则不需要
- export能直接导出变量表达式, export default不行
- require: node和ES6都支持的引入
- export/import:只用ES6支持的导出与引入
- module.exports/exports只有node支持的导出
eg1:
01.jsvar a=1; //变量var b=['arr1','arr2']; //数组var c={name:'对象',age:12}; //对象var d=function t1(){ //函数 console.log("函数");}/* 方法1:module.exports导出 module.exports.a=a; module.exports.b=b; module.exports.c=c; module.exports.d=d; *//* 方法2:module.exports直接导出 module.exports={ a,b,c,d} *//* 方法3:exports导出 exports.a=a; exports.b=b; exports.c=c; exports.d=d; */02.jsconst s=require("./01.js");console.log(s.a);console.log(s.b) console.log(s.c.name);s.d();console.log(s);
eg2:
03.jsfunction Demo(){ this.a="类属性"; this.b=function(){ console.log("类方法"); }}module.exports=Demo;04.jsconst Demo=require("./03.js");var demo=new Demo(); console.log(demo.a);demo.b();
eg3:
module.exports直接赋值导出 module.exports={ 'b':function(){ console.log('哈哈'); }} exports.b=function(){ console.log('哈哈');}