一、CommonJS规范
1、简介
Node应用由模块组成,采用CommonJS规范。每一个文件就是一个模块,有自己的作用域。在一个文件里面定义的变量、函数、类都是私有的,对其他文件不可见。
2、基本语法
- 定义暴露模块: exports.xxx = value 或者module.exports = value
- 引入模块:require(xxx),如果是Node提供的核心模块,xxx就是模块名称;如果是由用户编写的文件模块,xxx为文件模块的路径。
for example 1:
exports.name="jinggege";
exports.age = 18;
exports.add = function(a,b){
return a+b;
}
引入模块打印结果如下图:
exports.xxx 是给exports对象添加属性,可以多次添加.
for example 2:
module.exports = {
name:'jinggege',
age:18
}
module.exports = {
add:function(a,b){
return a+b;
}
}
引入模块打印结果如下图:
module.exports 是给module对象的exports属性赋值,再次添加会将上次的值覆盖掉,只能添加一次。
3、实现原理
那CommonJS暴露的到底是什么呢?
CommonJS规范规定,每个模块内部,module变量表示当前模块。这个变量是一个对象,它的exports属性(module.exports)是对外的接口。暴露模块的本质是:将exports对象暴露。加载某个模块,其实是加载该模块的exports属性。
那在模块中,我们并未看到定义module这个变量,这个变量到底是谁提供的呢?
我们通过在模块中打印 arguments.callee 可以观察到当前执行的函数对象
exports.a = 10
console.log(arguments.callee + '')
由打印结果我们可以发现,当node在执行模块代码时,它会给代码的外层裹上一个函数,这个函数有五个参数,分别是:
- exports:该对象用来将变量或函数暴露到外部
- require:函数,用来引入外部的模块
- module:module代表的是当前模块本身,exports就是module的属性,所以我们既可以使用exports导出,也可以使用module.exports导出。
- __filename : 表示当前模块的完整路径
- __dirname:表示当前模块所在文件夹的完整路径