我也来为你们分析分析 node.js 中 exports 和 module.exports 的简单区别javascript
首先明确一点 module.exports = exports = {},在初始化的时候是这样的,这里 exports 做为 module.exports 的一个辅助工具存在。而 js 的对象是以引用传值的方式存在的,因此两者此时指向的是同一地址。java
注意:这里必定要理解 js 的一些数据类型的特性,像咱们经常使用的数值,字符串,布尔他们都是值传递的,而数组,对象都是引用传递的node
foo = bar = 10 foo 和 bar 此时指向同一地址 foo = 20 js 新建了一个 20 的常量,并让 foo 指向它,此时 bar 指向的依然为 10 bar // 10 foo = bar = {} foo 和 bar 此时指向同一地址 foo.name = "big_cat" 此时 js操做的依然为 foo 和 bar 指向的对象 bar.name // big_cat //若是 foo = {"name": "other"} // js 新建一个对象 并让 foo 指向它 foo 已经切断了和前对象的联系 bar.name // big_cat
当你 require 某个模块文件时,承接上下文的实际上是 module.exports,是他将引入的文件封装成一个模块,而后传递给你,你就拿到了引用模块的接口。数组
exports的使用方法工具
/** * person.js */ exports.eat = function(food = '') { console.log("person eats " + food); } exports.drink = function(drinking = '') { console.log("person drinks " + drinking); }
exports 在初始化时做为 module.exports 的一个副本工具,如上所示增长成员,就等同于给 module.exports 增长成员,顺理而然的 require 使用 module.exports 做为表明文件模块时也能够正常使用ui
but,若是你这样用spa
exports = { eat:function(food) { console.log("person eats " + food); }, drink: function(drinking) { console.log("person drinks " + drinking); } }
要知道,你这里是给 exports 从新初始化并赋值了,他完全的和 module.exports 脱离的关系,他完全的变成了你模块文件里的一个变量code
因此若是你这样写了还像往常同样引入文件模块,调用其上的方法时,就该报错了,由于 module.exports 的值为 NULL,exports 已经完全断绝了与 module.exports 的关系了,他不会把本身的成员交给 module.exports,进而让你正常引用了,它只是一个普通的变量了。对象
应该这样写接口
module.exports = { eat:function(food) { console.log("person eats " + food); }, drink: function(drinking) { console.log("person drinks " + drinking); } }
如上写法你即可以正常引用模块文件而后调用对应的方法了,一个经过 require 引入的文件能够做为一个 module,而 module.exports 做为对外的接口,将本身封装的功能开放出去,供调用者使用
简单来讲
exports 在初始化的时候会被指命为 module.exports 的辅助工具,承接注册新的模块成员,在被模块被引入时将注册名单转交给 module.exports, module.exports 再转交给你,exports 对你是透明的
可是,若是你从新将 exports 初始化,他就脱离了 module.exports 的管控,因此他不会将你天真的注册给他的数据上报给 module.exports,因此你便访问不到你想要的方法。