源码网商城,靠谱的源码在线交易网站 我的订单 购物车 帮助

源码网商城

跟我学Nodejs(三)--- Node.js模块

  • 时间:2020-04-21 14:57 编辑: 来源: 阅读:
  • 扫一扫,手机访问
摘要:跟我学Nodejs(三)--- Node.js模块
简介及资料     通过Node.js的官方API可以看到Node.js本身提供了很多核心模块 http://nodejs.org/api/ ,这些核心模块被编译成二进制文件,可以require('模块名')去获取;核心模块具有最高的加载优先级(有模块与核心模块同名时会体现)     (本次主要说自定义模块)     Node.js还有一类模块为文件模块,可以是JavaScript代码文件(.js作为文件后缀)、也可以是JSON格式文本文件(.json作为文件后缀)、还可以是编辑过的C/C++文件(.node作为文件后缀);     文件模块访问方式通过require('/文件名.后缀')    require('./文件名.后缀')    requrie('../文件名.后缀') 去访问,文件后缀可以省略;以"/"开头是以绝对路径去加载,以"./"开头和以"../"开头表示以相对路径加载,而以"./"开头表示同级目录下文件,     前面提到文件后缀可以省略,Nodejs尝试加载的优先级 js文件 > json文件 > node文件 [b]创建一个自定义模块[/b]    以一个计数器为例 [img]http://files.jb51.net/file_images/article/201405/2014525101117814.png?2014425101144[/img]
[u]复制代码[/u] 代码如下:
var outputVal  = 0;     //输出值 var increment = 1;    //增量 /* 设置输出值 */ function seOutputVal (val) {     outputVal = val; } /* 设置增量 */ function setIncrement(incrementVal){     increment = incrementVal; } /* 输出 */ function printNextCount() {        outputVal += increment;     console.log(outputVal) ; } function printOutputVal() {     console.log(outputVal); } exports.seOutputVal = seOutputVal; exports.setIncrement = setIncrement; module.exports.printNextCount = printNextCount; 自定义模块 示例源码
示例中重点在于exports和module.exports;提供了外部访问的接口,下面调用一下看看效果吧 [b]调用自定义模块[/b] [img]http://files.jb51.net/file_images/article/201405/2014525101219705.png?2014425101236[/img]
[u]复制代码[/u] 代码如下:
/*     一个Node.js文件就是一个模块,这个文件可能是Javascript代码、JSON或者编译过的C/C++扩展。     重要的两个对象:     require是从外部获取模块     exports是把模块接口公开    */ var counter = require('./1_modules_custom_counter'); console.log('第一次调用模块[1_modules_custom_counter]'); counter.seOutputVal(10);               //设置从10开始计数 counter.setIncrement (10);             //设置增量为10 counter.printNextCount(); counter.printNextCount(); counter.printNextCount(); counter.printNextCount(); /*     require多次调用同一模块不会重复加载 */ var counter = require('./1_modules_custom_counter'); console.log('第二次调用模块[1_modules_custom_counter]'); counter.printNextCount(); 自定义模式调用 源码
    运行可以发现通过exports和module.exports对外公开的方法都可以访问!     示例中可以看到,我两次通过require('./1_modules_custom_counter')获取模块,但是第二次引用后调用printNextCount()方法确从60开始~~~     原因是node.js通过requirerequire多次调用同一模块不会重复加载,Node.js会根据文件名缓存所有加载过的文件模块,所以不会重新加载了     注意:通过文件名缓存是指实际文件名,并不会因为传入的路径形式不一样而认会是不同的文件         在我创建的1_modules_custom_counter文件中有一个printOutputVal()方法,它并没有通过exports或module.exports提供对外公开访问方法,     如果1_modules_load文件中直接访问运行会出现什么样的情况呢?     答案是:TypeError: Object #<Object> has no method 'printOutputVal' [b]exports和module.exports 区别[/b] 经过上面的例子,通过exports和module.exports对外公开的方法都可以访问!那既然两种都能达到效果,但总得有点区别的吧~~~用个例子看看吧! [img]http://files.jb51.net/file_images/article/201405/2014525101343453.png?2014425101356[/img]
[u]复制代码[/u] 代码如下:
var counter  = 0;     exports.printNextCount = function (){        counter += 2;     console.log(counter); } var isEq = (exports === module.exports); console.log(isEq); 2_modules_diff_exports.js 文件源码
下面再新建个2_modules_diff_exports_load.js文件调用一下 [img]http://files.jb51.net/file_images/article/201405/2014525101436427.png?2014425101451[/img]
[u]复制代码[/u] 代码如下:
var Counter = require('./2_modules_diff_exports'); Counter.printNextCount();
    调用后,执行结果如上图     我在2_modules_diff_exports_load.js文件中输出了isEq的值  ( var isEq = (exports === module.exports); ),返回的true     PS:注意是三个等号,如果不清楚自已查查资料吧! 不用急着下结论,把这两个JS文件分别改成module.exports对应的代码
[u]复制代码[/u] 代码如下:
//修改后的2_modules_diff_exports.js源码如下 var counter  = 0;     module.exports = function(){        counter += 10;     this.printNextCount = function()     {         console.log(counter);        } } var isEq = (exports === module.exports); console.log(isEq);
[u]复制代码[/u] 代码如下:
//修改后的2_modules_diff_exports_load.js文件源码如下 var Counter = require('./2_modules_diff_exports'); var counterObj = new Counter(); counterObj.printNextCount();
[img]http://files.jb51.net/file_images/article/201405/2014525101511367.png?2014425101523[/img]     调用后,执行结果如上图     我在2_modules_diff_exports_load.js文件中输出了isEq的值  ( var isEq = (exports === module.exports); ),返回的false,这与用先前得到的结果不一致!     PS:不要用Counter.printNextCount();去访问,你只会得到一个错误的提示     API提供了解释     http://nodejs.org/api/modules.html     Note that exports is a reference to module.exports making it suitable for augmentation only. If you are exporting a single item such as a constructor you will want to use module.exports directly instead     exports仅仅是module.exports的一个地址引用。nodejs只会导出module.exports的指向,如果exports指向变了,那就仅仅是exports不在指向module.exports,于是不会再被导出     参考其它理解:     http://www.hacksparrow.com/node-js-exports-vs-module-exports.html     http://zihua.li/2012/03/use-module-exports-or-exports-in-node/     module.exports才是真正的接口,exports只不过是它的一个辅助工具。 最终返回给调用的是module.exports而不是exports。     所有的exports收集到的属性和方法,都赋值给了Module.exports。当然,这有个前提,就是module.exports本身不具备任何属性和方法。     如果,module.exports已经具备一些属性和方法,那么exports收集来的信息将被忽略。 [b]exports和module.exports 覆盖[/b] 上面也也基本明白了exports和module.exports的关系和区别,但如果同时针对printNextCount()方法存在exports和module.exports,结果如何? [img]http://files.jb51.net/file_images/article/201405/2014525101724890.png?2014425101737[/img] 调用结果 [img]http://files.jb51.net/file_images/article/201405/2014525101924021.png?2014425101942[/img]     从结果可以看出,并没有报错,表示可以这么定义,但最终module.exports覆盖了exports     虽然结果不会报错,如果这么用开发中难免会有一些问题存在,所以     1.最好别分别定义module.exports和exports     2.NodeJs开发者建议导出对象用module.exports,导出多个方法和变量用exports [b]其它...[/b]    API中还提供了其它的方法,就不细讲了,在上面例子的基础上自已动手一输出就知道了   module.id   返回string类型的模块标识,一般为完全解析后的文件名   module.filename   返回一个string类型的完全解析后文件名   module.loaded   返回一个bool类型,表示是否加载完成   module.parent   返回引用该模块的模块   module.children   返回该模块引用的所有模块对象的数组
  • 全部评论(0)
联系客服
客服电话:
400-000-3129
微信版

扫一扫进微信版
返回顶部