谈谈module.exports和exports

2,037 阅读5分钟

谈谈module.exports和exports

module.exports 对象是由模块系统创建的。在我们自己写模块的时候,需要在模块最后写好模块接口,声明这个模块对外暴露什么内容,module.exports 提供了暴露接口的方法。

先用module.exports导出几个变量

//module.js
module.exports.name = "孙悟空";
module.exports.age = 1;
module.exports.sayname=function(){
    console.log("我一天不敲代码我就难受!");
}
//B.js
var moduleB=require('./module');
console.log(moduleB.name);//孙悟空
moduleB.sayname()//我一天不敲代码我就难受!

上面代码module.js导出了变量name和age、函数sayname,在B.js文件中得出输出

module.exports导函数

//B.js
var moduleB=require('./module');
var c=new moduleB(1,2)
console.log(c);

//结果是
//3
//add {}
//module.js
var add=function(a,b){
    console.log(a+b);
}
module.exports=add

可见可以通过new来创建对象等到里的结果

CommonJS规范规定,每个模块内部,module变量代表当前模块。这个变量是一个对象,它的exports属性(即module.exports)是对外的接口。加载某个模块,其实是加载该模块的module.exports属性。

//module.js
var x=5;
var add=function(a,b){
    // console.log(a+b);
    return a+b;
   
}
module.exports.x=x
module.exports.add=add

//B.js
var moduleB=require('./module');
console.log(moduleB.x);//5
console.log(moduleB.add(1,2));//3

前面讲解了module.exports基本导入变量和函数,那如果函数和变量过多怎么办可以使用一下方法进行简化

//module.js
var x=5;
var add=function(a,b){
    // console.log(a+b);
    return a+b;
   
}
var diverse=function(a,b){
    return a/b;
}
module.exports={x,add,diverse}

//B.js
var moduleB=require('./module');
console.log(moduleB.x);
console.log(moduleB.add(1,2));
console.log(moduleB.diverse(4,2));
//5
//3
//2

或则

var {x,add,diverse}=require('./module');
console.log(x,add(1,2),diverse(4,2));
//5
//3
//2

下面介绍exports与module.exports

exports 与 module.exports

优先使用 module.exports

为了方便,Node为每个模块提供一个exports变量,指向module.exports。这等同在每个模块头部,有一行这样的命令

var exports = module.exports;

​ 您可以在模块中使用的魔法变量 - exportsrequiremodule__filename__dirname不是魔法,它们只是加载模块时调用的函数的参数。

最初,exportsmodule.exports指向同一个*空*对象

image-20211011140034406

您可以使用module.exportsexports因为它们都指向同一个对象,所以您可以向该对象添加属性,所以您使用哪个并不重要

如果添加exports.foo = "bar"module.exports.baz = "boz"那么你的模块的输出对象将是这样的:

{foo: "bar", baz: "boz"}

**exports **返回的是模块函数

**module.exports 返回的是模块对象本身,返回的是一个类 ** 使用上的区别是:

  1. exports的方法可以直接调用
  2. module.exports需要new对象之后才可以调用
  3. 当一个模块需要导出单个成员的时候,这个时候必须使用:module.exports = xxx 的方 式,不要使用 exports = xxx 不管用

二话不说,撸代码!

//A.js
var test=require('./exports_module')
console.log(test.add(1,2));//3
//expoets_module.js
var add=function(a,b){
    return a+b;
}
exports.add=add;

我们再看看用module.exports

//B.js
var test=require('./module');
console.log(test.add(1,2));//3

var add=function(a,b){
    return a+b;
}
exports.add=add;

发现此时exports和module.exports输出的都是一样的

为什么module.exports也有exports方法了,简单点理解就是

**exports是module.exports的一个引用,exports指向的是module.exports**

我们用代码判断一下

console.log(exports === module.exports)//true

说明exports和module.exports是同一个对象

只不过是一开始exports和module.exports指向的都是同一个空对象

随着对象的改变而改变

exports、module.exports 和 export、export default 到底是咋回事

require: node 和 es6 都支持的引入 export / import : 只有es6 支持的导出引入 module.exports / exports: 只有 node 支持的导出 Node里面的模块系统遵循的是CommonJS规范。那问题又来了,什么是CommonJS规范呢? 由于js以前比较混乱,各写各的代码,没有一个模块的概念,而这个规范出来其实就是对模块的一个定义。 CommonJS定义的模块分为: 模块标识(module)、模块定义(exports) 模块引用(require)

先解释 exports 和 module.exports 在一个node执行一个文件时,会给这个文件内生成一个 exports和module对象, 而module又有一个exports属性。他们之间的关系如下图,都指向一块{}内存区域。

exports = module.exports = {};复制代码

exports 只是 module.exports的引用,辅助后者添加内容用的。

ES中的模块导出导入

说实话,在es中的模块,就非常清晰了。不过也有一些细节的东西需要搞清楚。比如 export 和 export default,还有 导入的时候,import a from ..,import {a} from ..,总之也有点乱,那么下面我们就开始把它们捋清楚吧。

export 和 export default

首先我们讲这两个导出,下面我们讲讲它们的区别

  1. export与export default均可用于导出常量、函数、文件、模块等
  2. 在一个文件或模块中,export、import可以有多个,export default仅有一个
  3. 通过export方式导出,在导入时要加{ },export default则不需要
  4. export能直接导出变量表达式,export default不行。
'use strict'
//导出变量
export const a = '100';  
 
 //导出方法
export const dogSay = function(){ 
    console.log('wang wang');
}
 
 //导出方法第二种
function catSay(){
   console.log('miao miao'); 
}
export { catSay };
 
//export default导出
const m = 100;
export default m; 
//export defult const m = 100;// 这里不能写这种格式。复制代码
//index.js
'use strict'
var express = require('express');
var router = express.Router();
 
import { dogSay, catSay } from './testEs6Export'; //导出了 export 方法 
import m from './testEs6Export';  //导出了 export default 
 
import * as testModule from './testEs6Export';//as 集合成对象导出
 
 
 
/* GET home page. */
router.get('/', function(req, res, next) {
  dogSay();
  catSay();
  console.log(m);
  testModule.dogSay();
  console.log(testModule.m); // undefined , 因为  as 导出是 把 零散的 export 聚集在一起作为一个对象,而export default 是导出为 default属性。
  console.log(testModule.default); // 100
  res.send('恭喜你,成功验证');
});
 
module.exports = router;