module.exports 与 exports.xxx 的区别

1. 原理解析

NodeJS中使用了CommonJS的模块化标准,Node内部提供一个Module构建函数。所有模块都是Module的实例。每个模块内部,都有一个module对象,代表当前模块。而这个module对象中,就存在一个成员 exports,该成员也是一个对象。也就是说,如果你需要对外导出成员,只需要把导出的成员挂载到 module.exports 上就可以了,最终module对象中会执行 retrun module.exports 将挂载的值返回给require的对象。

var module = {
    exports: {
        // 挂载的对象都放到这里
    }
}

所以,原理是你是可以这么写的

function add(a, b) {
    return a + b
}

module.exports.add = add

运行结果也无报错
module.exports 与 exports.xxx 的区别_第1张图片
但是你会发现,这样做的话,每次都需要写那么长的一截 module.exports.xxx ,很麻烦,于是就引入一个 exports 变量 (注意:就只是个变量名,不是module里面的那个exports对象)
var exports = module.exports;
如果是学过指针或者对数据结构比较熟悉的同学,一看到这个代码就明白是怎么一回事了,它是一个引用传递,就只是把 exports 指向了和module.exports 的同一块内存空间。
module.exports 与 exports.xxx 的区别_第2张图片
因此,exports变量就可以向exports对象中添加方法或属性
也就是说exports.addmodule.exports.add 的作用是一样的。
而当你操作exports变量指向其他空间的时候,它就与exports对象断联了,比如说: exports = add,这个语句是直接将exports指向了add 方法的返回值
module.exports 与 exports.xxx 的区别_第3张图片

2. 用法区别

一般来说,导出多个成员可以沟通过使用多个 exports.xxx = xxx 或者使用一个 module.exports = {}的方式来实现,而导出单个成员时使用module.exports = xxx

你肯定很疑惑为什么说导出单个的时候使用 module.exports = xxx ?人家做exports变量不就是方便你使用的吗?你怎么辜负别人的好心?

举个例子你就明白了

还是上面的那个两数相加的案例,和上面不同的是,我直接写了module.exports = add 而不是 module.exports.add = add

function add(a, b) {
    return a + b
}

module.exports = add

接下来我在另外一个文件中,导入这个文件,并调用它的add方法。

const wantAdd = require('./module')
console.log(wantAdd(1,2))

输出的结果为 3
在这里插入图片描述
而如果改成了 exports.add = add 的方式导出的话

const wantAdd = require('./module')

// console.log(wantAdd(1,2))
console.log(wantAdd.add(1,2))

输出结果同样为3
在这里插入图片描述
那有什么不同呢? 聪明的你一定发现了,使用 module.exports = xxx 的时候,我调用 add 方法是直接通过 wantAdd(1, 2) 来实现的;而使用 exports.add = add 的时候,调用add方法需要通过 wantAdd.add(1, 2) 来实现的。
原理就是由于module.exports = xxx是直接导出了 exports对象,也就说exports对象就是add方法;而exports.add = add 相当于 module.exports.add = add ,是在 exports 中新加了一个变量去指向 add 方法,所以你用wantAdd变量接收exports对象时,还需要调用 add 变量去使用到 add方法。
所以在导出单个的时候,使用 module.exports 会更方便些。

总结

exports 与 module.exports 本是同根生,在用法上稍稍不同,原理上也比较简单易懂。exports.xxx = xxx 在传递多个对象的时候,写法看起来优雅一些,算是一种快捷方式。若你实在是感受不到 exports 的好处或者分不清 exports变量与module.exports的区别,那你就使用module.exports 就好了,绝对不会有问题的。

你可能感兴趣的:(nodejs,nodejs,module.exports,exports)