exports和module.exports区别
1、分析
我们可以从底层实现去理解:在node里每个模块内部都有一个自己的对象module,而该module对象里,有一个子对象exports
在node里,谁require该文件,谁就得到module.exports接口对象
我们发现,每次导出接口成员时通过module.exports.xxx = xxx的方式很麻烦,都得通过点.方式 因此node为了简化操作,专门提供了一个变量:exports = module.exports
也就是说在模块底层实现里,还有这么一句代码
var exports = module.exports
测试如下
2、原理解析
exports是module.exports的一个引用
3、导出单个模块
当导出单个模块时,需要module.exports即可
4、思考进阶(面向对象--引用类型)
为什么导出单个对象不可以使用exports = xxx;直接赋值定义导出???
原理图:引用数据类型
接下来再看个思考题
结果为hello,为什么呢?
当给obj1重新赋值后,它便指向了新对象,开辟了新的内存空间,如下所示,此时两者已经没有关系
综上分析不能使用exports = xxx来直接导出单个成员
var exports = module.exports
类似于
var obj1 = obj
这里exports只是module.exports的一个引用,所以这里直接给exports直接赋值,并不会影响module.exports,只是指向了新对象而已。
始终要记住:底层实现里最后返回的是module.exports对象
5、重新赋值,解除引用
此外,这里要注意:一旦给exports重新赋值,便会失去和module.exports的关联,指向新对象,且后期无法使用。
如下所示
6、思考2
对上述代码再次修改如下
结果如下
7、思考3
再使用module.exports添加如下
8、思考4
接下来再做下调整
原理如下:
换为exports与module.exports
重定义
这里注意:此时两者已经没有引用关系,最终return的是module.exports所以只需要看module.exports即可
9、思考5
接着修改代码
10、思考6
11、小结
1、exports为modules.exports的一个引用 2、最后node底层模块导出的是module.exports 3、底层代码 var module = { exports:{...} } 4、exports.name等价于module.exports.name,但node为了方便书写,使用module.exports导出单个成员,本质为将该子对象重新赋值
5、所以只要给exports赋值,便丢失了module.exports的引用关系,后期便不可用
.