前言:
Node.js中的模块就相当于JAVA语言里面的类,在模块中包含成员变量和成员方法
学过JAVA 的朋友可以将模块当成JAVA类来学习
当我们在js当中定义一个变量 var a = 10 我们可以通过window.a的方式去访问a
可以说这个a是一个全局变量也可以说a是window底下的一个属性
但是在nodejs当中我们没有window对象,同时我们也不能直接通过glabal(nodejs顶层
对 象)去直接访问,这就涉及到nodejs中的模块
我们在nodejs中定义的var a= 10 此时a只是存在于当前模块作用域
在nodejs中一个文件就是一个模块,每个模块都有自己的作用域,我们在一个js文件定义一个变量var a = 10 ,此时a 只是当前模块中的变量并不是全局的
我们可以在node中使用glabal.a=100 的方式去定义一个全局的变量,我们访问时也需要去访问glabal.a方可访问全局变量a,如果我们直接访问a那么我将访问当前模块下的变量a
1.创建模块
user.js的内容如下
function User(id,name,age) {
this.id=id;
this.name=name;
this.age=age;
this.shangban=function (res) {
res.write("我是"+this.name+",我要到公司了")
console.log("我是"+this.name+",我要到公司了");
}
}
//导出user
module.exports = User;
ps:在user.js中主要有id,name,age还有一个shangban的函数,我们使用module.exports来讲user导出,同时为user方法带入了三个参数用来构造user
我们再来创建一个http的服务来让我们在页面上输出也可以直接使用conlose.log()控制台输出
var http = require('http')
//使用require导入user
var User = require("./user")
http.createServer(function (request, response) {
// 发送 HTTP 头部
// HTTP 状态值: 200 : OK
// 内容类型: text/plain
//charset=utf-8防止中文乱码
response.writeHead(200, {'Content-Type': 'text/html;charset=utf-8'});
user = new User(1,'李四',20);
user.shangban(response);
response.end('')
}).listen(8888);
// 终端打印如下信息
console.log('Server running at http://127.0.0.1:8888/');
ps:我们在service.js中引入了user 并且对其进行了初始化调用了shangban函数进行页面和控制台的输出
2.继承
我们来创建一个boss.js模块继承user.js模块
boss.js内容如下:
var User = require("./user")
function Boss(id,name,age) {
//让当前模块继承与uesr模块
User.apply(this,[id,name,age]);
this.kaigongzi=function (res) {
res.write(this.name+"发很多工资")
}
}
//导出boss模块
module.exports = Boss;
在这里我们使用了apply方法让boss模块继承user模块
又为boss模块添加了自己的函数输出
我们在service.js中调用boss并且调用开工资函数
var http = require('http')
//使用require导入user
var Boss = require("./Boss")
http.createServer(function (request, response) {
// 发送 HTTP 头部
// HTTP 状态值: 200 : OK
// 内容类型: text/plain
//charset=utf-8防止中文乱码
response.writeHead(200, {'Content-Type': 'text/html;charset=utf-8'});
boss = new Boss(1,'李四',20);
boss.kaigongzi(response);
response.end('')
}).listen(8888);
// 终端打印如下信息
console.log('Server running at http://127.0.0.1:8888/');
页面结果:
同时我们也可以使用boss.shangban(response),来调用user.js里面定义的上班函数,因为boss继承了user同时业绩承了user的shangban函数
Node.js 中存在 4 类模块(原生模块和3种文件模块),尽管 require 方法极其简单,但是内部的加载却是十分复杂的,其加载优先级也各自不同。如下图所示:
献上一张菜鸟课程图片:
require方法接受以下几种参数的传递:
- http、fs、path等,原生模块。
- ./mod或../mod,相对路径的文件模块。
- /pathtomodule/mod,绝对路径的文件模块。
- mod,非原生模块的文件模块。
在路径 Y 下执行 require(X) 语句执行顺序:
1. 如果 X 是内置模块
a. 返回内置模块
b. 停止执行
2. 如果 X 以 '/' 开头
a. 设置 Y 为文件根路径
3. 如果 X 以 './' 或 '/' or '../' 开头
a. LOAD_AS_FILE(Y + X)
b. LOAD_AS_DIRECTORY(Y + X)
4. LOAD_NODE_MODULES(X, dirname(Y))
5. 抛出异常 "not found"
LOAD_AS_FILE(X)
1. 如果 X 是一个文件, 将 X 作为 JavaScript 文本载入并停止执行。
2. 如果 X.js 是一个文件, 将 X.js 作为 JavaScript 文本载入并停止执行。
3. 如果 X.json 是一个文件, 解析 X.json 为 JavaScript 对象并停止执行。
4. 如果 X.node 是一个文件, 将 X.node 作为二进制插件载入并停止执行。
LOAD_INDEX(X)
1. 如果 X/index.js 是一个文件, 将 X/index.js 作为 JavaScript 文本载入并停止执行。
2. 如果 X/index.json 是一个文件, 解析 X/index.json 为 JavaScript 对象并停止执行。
3. 如果 X/index.node 是一个文件, 将 X/index.node 作为二进制插件载入并停止执行。
LOAD_AS_DIRECTORY(X)
1. 如果 X/package.json 是一个文件,
a. 解析 X/package.json, 并查找 "main" 字段。
b. let M = X + (json main 字段)
c. LOAD_AS_FILE(M)
d. LOAD_INDEX(M)
2. LOAD_INDEX(X)
LOAD_NODE_MODULES(X, START)
1. let DIRS=NODE_MODULES_PATHS(START)
2. for each DIR in DIRS:
a. LOAD_AS_FILE(DIR/X)
b. LOAD_AS_DIRECTORY(DIR/X)
NODE_MODULES_PATHS(START)
1. let PARTS = path split(START)
2. let I = count of PARTS - 1
3. let DIRS = []
4. while I >= 0,
a. if PARTS[I] = "node_modules" CONTINUE
b. DIR = path join(PARTS[0 .. I] + "node_modules")
c. DIRS = DIRS + DIR
d. let I = I - 1
5. return DIRS
如果遇到问题的话可以加我qq讨论一下 1311353736