|
阅读:7584回复:0
nodejs中exports与module.exports的区别
为了更好的理解 exports 和 module.exports 的关系,我们先来巩固下 js 的基础。示例:
test.js var a = {name: 1}; var b = a; console.log(a); console.log(b); b.name = 2; console.log(a); console.log(b); var b = {name: 3}; console.log(a); console.log(b); 运行 test.js 结果为: { name: 1 } { name: 1 } { name: 2 } { name: 2 } { name: 2 } { name: 3 } 解释:a 是一个对象,b 是对 a 的引用,即 a 和 b 指向同一块内存,所以前两个输出一样。当对 b 作修改时,即 a 和 b 指向同一块内存地址的内容发生了改变,所以 a 也会体现出来,所以第三四个输出一样。当 b 被覆盖时,b 指向了一块新的内存,a 还是指向原来的内存,所以最后两个输出不一样。 明白了上述例子后,我们只需知道三点就知道 exports 和 module.exports 的区别了:
那到底Module.exports是什么呢?它是否合法呢? 其实,Module.exports才是真正的接口,exports只不过是它的一个辅助工具。 最终返回给调用的是Module.exports而不是exports。 所有的exports收集到的属性和方法,都赋值给了Module.exports。当然,这有个前提,就是Module.exports本身不具备任何属性和方法。如果,Module.exports已经具备一些属性和方法,那么exports收集来的信息将被忽略。 修改rocker.js如下: module.exports = 'ROCK IT!'; exports.name = function() { console.log('My name is Lemmy Kilmister'); }; 再次引用执行rocker.js var rocker = require('./rocker.js'); rocker.name(); // TypeError: Object ROCK IT! has no method 'name' 发现报错:对象“ROCK IT!”没有name方法 rocker模块忽略了exports收集的name方法,返回了一个字符串“ROCK IT!”。由此可知,你的模块并不一定非得返回“实例化对象”。你的模块可以是任何合法的javascript对象--boolean, number, date, JSON, string, function, array等等。 你的模块可以是任何你设置给它的东西。如果你没有显式的给Module.exports设置任何属性和方法,那么你的模块就是exports设置给Module.exports的属性。 其他模块内使用require引用的是module.exports 对象,不一定是exports指向的引用对象,这点在开发中很容易因为忽略而导致bug产生 解决方案: exports = module.exports = somethings 上面的代码等价于: module.exports = somethings exports = module.exports 原理很简单,即 module.exports 指向新的对象时,exports 断开了与 module.exports 的引用,那么通过 exports = module.exports 让 exports 重新指向 module.exports 即可 参考: http://cnodejs.org/topic/5231a630101e574521e45ef8 http://www.cnblogs.com/ooooevan/p/5897586.html |
|