Node.js教程 初步理解module
小作 2018-01-03 来源 :网络 阅读 1202 评论 0

摘要:此篇Node.js教程将教大家初步理解module。在开发一个复杂的应用程序的时候,我们需要把各个功能拆分、封装到不同的文件,在需要的时候引用该文件。没人会写一个几万行代码的文件,这样在可读性、复用性和维护性上都很差,几乎所有的编程语言都有自己的模块组织方式,比如Java中的包、C#中的程序集等,node.js使用模块和包来组织,其机制实现参照了CommonJS标准,虽未完全遵守,但差距不大,使用起来非常简单。

此篇Node.js教程将教大家初步理解module。在开发一个复杂的应用程序的时候,我们需要把各个功能拆分、封装到不同的文件,在需要的时候引用该文件。没人会写一个几万行代码的文件,这样在可读性、复用性和维护性上都很差,几乎所有的编程语言都有自己的模块组织方式,比如Java中的包、C#中的程序集等,node.js使用模块和包来组织,其机制实现参照了CommonJS标准,虽未完全遵守,但差距不大,使用起来非常简单。


什么是模块

在node.js中模块与文件是一一对应的,也就是说一个node.js文件就是一个模块,文件内容可能是我们封装好的一些JavaScript方法、JSON数据、编译过的C/C++拓展等,在关于node.js的误会提到过node.js的架构

Node.js教程  初步理解module

其中http、fs、net等都是node.js提供的核心模块,使用C/C++实现,外部用JavaScript封装。


创建、加载模块

模块在node.js中的概念很简单,看看如何创建一个我们自己的模块供开发复用。

在node.js中创建模块非常简单,一个文件就是一个模块,所以我们创建一个test.js文件就创建了一个模块

test.js
var name='';
function setName(n){
    name=n;
} 
function printName(){
    console.log(name);
}

 问题是怎么使外部访问这个module,我们知道客户端的JavaScript使用script标签引入JavaScript文件就可以访问其内容了,但这样带了的弊端很多,最大的就是作用域相同,产生冲突问题,以至于前端大师们想出了立即执行函数等方式,利用闭包解决。node.js使用exports和require对象来解决对外提供接口和引用模块的问题。

我们可以把模块中希望被外界访问的内容定义到exports对象中,对test.js稍作修改就可以了

test.js
var name='';
function setName(n){
    name=n;
} 
function printName(){
    console.log(name);
}
exports.setName=setName;
exports.printName=printName;

这样我们在相同路径下创建index.js,使用require引用一下test.js module

index.js
var test=require('./test');
test.setName('Byron');
test.printName();


exports一个对象

有时候我们希望模块对外提供的使一个对象,修改一下test.js

test.js
var Student=function(){
    var name='';
     this.setName=function(n){
        name=n;
    }; 
    this.printName=function(){
        console.log(name)    ;
    };
};
exports.Student=Student;


 这样我们对外提供了一个Student类,在使用的时候需要这样

var Student=require('./test').Student;var student=new Student();
student.setName('Byron');
student.printName();
 require('./test').Student 很丑陋的样子,我们可以简单修改一下exports方式,使require优雅一些
test.js
var Student=function(){
    var name='';
     this.setName=function(n){
        name=n;
    }; 
    this.printName=function(){
        console.log(name)    ;
    };
};
module.exports=Student;


 这样我们的require语句就可以优雅一些了

var Student=require('./test');

 

很神奇的样子,不是说好的exports是模块公开的接口嘛,那么module.exports是什么东西?


module.exports与exports

事实的情况是酱紫的,其实module.exports才是模块公开的接口,每个模块都会自动创建一个module对象,对象有一个modules的属性,初始值是个空对象{},module的公开接口就是这个属性——module.exports。既然如此那和exports对象有毛线关系啊!为什么我们也可以通过exports对象来公开接口呢?

为了方便,模块中会有一个exports对象,和module.exports指向同一个变量,所以我们修改exports对象的时候也会修改module.exports对象,这样我们就明白网上盛传的module.exports对象不为空的时候exports对象就自动忽略是怎么回事儿了,因为module.exports通过赋值方式已经和exports对象指向的变量不同了,exports对象怎么改和module.exports对象没关系了。

大概就是这么过程

module.exports=exports={};
......
module.exports=new Object();


exports=xxx;//和new Object没有关系了,最后返回module.exports,所以改动都无效了


一次加载

无论调用多少次require,对于同一模块node.js只会加载一次,引用多次获取的仍是相同的实例,看个例子

test.js
var name='';
function setName(n){
    name=n;
} 
function printName(){
    console.log(name);
}
exports.setName=setName;
exports.printName=printName;
 
index.js
var test1=require('./test'),
    test2=require('./test');
test1.setName('Byron');
test2.printName();

Node.js教程  初步理解module

 

执行结果并不是'',而是输出了test1设置的名字,虽然引用两次,但是获取的是一个实例


require搜索module方式

node.js中模块有两种类型:核心模块和文件模块,核心模块直接使用名称获取,比如最长用的http模块

var http=require('http');

 

在上面例子中我们使用了相对路径 './test'来获取自定义文件模块,那么node.js有几种搜索加载模块方式呢?

1.核心模块优先级最高,直接使用名字加载,在有命名冲突的时候首先加载核心模块

文件模块只能按照路径加载(可以省略默认的.js拓展名,不是的话需要显示声明书写)

.绝对路径

.相对路径

2.查找node_modules目录,我们知道在调用 npm install <name> 命令的时候会在当前目录下创建node_module目录(如果不存在) 安装模块,当 require 遇到一个既不是核心模块,又不是以路径形式表示的模块名称时,会试图 在当前目录下的 node_modules 目录中来查找是不是有这样一个模块。如果没有找到,则会 在当前目录的上一层中的 node_modules 目录中继续查找,反复执行这一过程,直到遇到根目录为止。


看完此文module你能理解了吗?总之,同学们,你想要的职坐标IT频道都能找到!



本文由 @小作 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程