您的位置:首页 > 其它

07 module.exports和moudle和exports的区别很容易理解

2016-10-29 23:57 267 查看
  看完你就理解node.js中的module.exports、moudle、exports

有些童鞋在开始学习node的时候不清楚模块(module)的概念,,现在我们带着问题慢慢来了解:

一:为什么node需要用module.exports?

Node程序由很多模块组成,每个模块就是一个文件。

并且Node模块采用了个CommonJs规范(下文会详细说明)

根据CommonJs规范一个单独的文件就是一个模块。每个模块都是一个 单独的作用域。也就是说:一个文件中的所有变量、类、方法都是私有的, 别的文件是不可见,不能直接引用的。

例如:我们创建一个js文件a.js

var name1 = ‘bangbang’;

var name2 = function(name){

return name;

}

上面文件中:变量name1和name2在当前的文件中是私有的,其他文件不 可见。

在javascript中有2种作用域:全局作用域和函数作用域,在浏览器端, 全局作用域就是window对象的属性,函数作用域就是函数内部的对象属性。

在node中,也有2种作用域:全局作用域和模块作用域,因此要想实现在nodejs中多个文件中分享变量,就必须定义成全局对象 (global)的属性, global定义的变量,在任何地方都可以使用,类似于浏览器端定义在全局 范围中的变量。Global可查看http://www.w3clog.com/20.html

例如:我们创建一个js文件:a1.js



再创建一个js文件:test.js,其中require用来引入外部文件。(以下都这样用)



定义在global上面的变量,不需要在模块中通过exports输出,其他模块中 也能使用,请看test.js在node中的输出:



上面代码的name1和name2变量可以被所有文件读取,当然,这样的写法是不推荐的,并且在外部文件读取的时候不方便。

因此:我们需要用module.exports对象。

二:什么是module.exports对象,该怎么使用?

CommonJS规定:每个文件对外接口是module.exports对象。这个对象 的所有属性和方法都可以被其他文件导入。

例如:我们创建一个js文件:b1.js



再创建一个test2.js



Test2在node控制台的输出:



上面代码中的module.exports对象,定义对外接口,输出变量num1和函数add;

2.总之

module.exports对象可以被其他文件导入,其实他就是文件内部与文件外部通信的桥梁.

module.exports属性表示当前模块对外输出的接口,其他文件加载该模块,实际上就是读取module.exports变量。

例如:我们创建一个c1文件:(如果看不懂,请看我的日志node事件驱动)



然后我们创建另一个测试文件test3:



在node输出test3结果:



三. 那么:什么是module对象呢?

每个模块内部,都有一个module对象,代表当前的模块,他有以下属性:还是test2.js文件,后面加一句console.log(module);


再次看一下test2输出结果:



我们分析一下:

Module.id — 模块的识别符,通常是带有绝对路径的模块文件名;Module.filename – 模块的文件名,含有绝对路径;Module.loaded – 返回布尔值,代表模块是否已经完成加载;

Module.parent – 返回一个对象,表示调用该模块的模块;

Module.children – 返回一个数组,表示该模块要用到的其他模块。

四.什么是exports变量呢?

为了方便,Node为每个模块提供一个exports变量,(即引用赋值)指向module.exports,这等同于在每个模块头部有一行这样的命令:

Var exports = module.exports;

结果呢?在对外输出模块接口时,向exports对象添加方法:

例如:我们在c1.js后面添加代码:(如果实在看不懂,就看最后的总结,嘿嘿!)



以上在test3.js引用的时候出现错误!因为exports不再指向module.exports;

因此:注意:不能直接将exports变量指向一个值,因为这样等于切断了,exports与module.exports的联系。

下面的代码也是无效的,name函数无法对外输出,



为什么module和module.exports混和使用不行?

这个很重要:因为module.exports被重新赋值了。require返回的是module.exports的值,module.exports才是真正的接口,而不是exports的值;因此如果你觉得exports与module.exports很难分清,一个简单的处理方法就是:尽量让他们只出现一种,不要混合使用!推荐使用exports导出方法或者变量。

## 标题 ##

详细请看:http://cnodejs.org/topic/5231a630101e574521e45ef8

五:为什么node用CommonJS规定的模块方式加载?

&ems;&ems;以下为Commonjs模块的特点:

1. 所有代码都运行在模块中,不会污染全局作用域;

2. 模块可以多次加载,但是只会在第一次加载时运行一次,然后运行结果 就被缓存了,以后再次加载的时候就直接读取缓存结果。要想让模块再次 运行,必须清除缓存。

3. 模块加载的顺序,按照其在代码中出现的顺序。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: