JavaScript 中有一个特殊的对象,称为全局对象(Global Object),它及其所有属性都可以在程序的任何地方访问,即全局变量。
在浏览器 JavaScript 中,通常 window 是全局对象, 而 Node.js 中的全局对象是 global,所有全局变量(除了 global 本身以外)都是 global 对象的属性。
在 Node.js 我们可以直接访问到 global 的属性,而不需要在应用中包含它。
全局模块(对象)
特征:何时何地都可以访问,不需要引用
- process 对象是一个全局变量,它提供当前 Node.js 进程的有关信息,以及控制当前 Node.js 进程。 因为是全局变量,所以无需使用 require()。
-
process.env (环境变量),我们可以通过console.log(),打印一下
image.png
常用来判断是生产环境还是开发环境
image.png
-
process.argv 属性返回一个数组,这个数组包含了启动Node.js进程时的命令行参数,打印出来后,发现:
数组的第一个元素process.argv[0]——返回启动Node.js进程的可执行文件所在的绝对路径
第二个元素process.argv[1]——为当前执行的JavaScript文件路径
image.png
如果我们在后边再打印一些东西,会发现后边的参数是依次排列的
image.png
由此我们可以获取这些参数做一些操作
image.png
- 一些常见的全局变量
__filename 表示当前正在执行的脚本的文件名。它将输出文件所在位置的绝对路径,且和命令行参数所指定的文件名不一定相同。 如果在模块中,返回的值是模块文件的路径。
image.png
__dirname 表示当前执行脚本所在的目录。
image.png
系统模块
特征:需要 require(),但是不需要单独下载,因为在按照node的时候已经内置好了
- path 模块
提供了一些实用工具,用于处理文件和目录的路径。 可以使用以下方式访问它:let path = require('path')
// 引入path模块
let path = require('path')
// path模块会有很多方法
// path.dirname() 方法会返回 path 的目录名
console.log(path.dirname('/node/a/b/c/1.jpg')) // /node/a/b/c
// path.basename() 方法会返回 path 的最后一部分
console.log(path.basename('/node/a/b/c/1.jpg')) // 1.jpg
// path.extname() 方法会返回 path 的扩展名
console.log(path.extname('/node/a/b/c/1.jpg')) // .jpg
//path.join() 方法会将所有给定的 path 片段连接到一起,然后规范化生成的路径。
console.log(path.join('node', 'a', 'b', 'c/d', '1.jpg')) //node\a\b\c\d\1.jpg
// path.resolve() 方法会将路径或路径片段的序列解析为绝对路径。
// 给定的路径序列会从右到左进行处理,后面的每个 path 会被追加到前面,直到构造出绝对路径
// 如果在处理完所有给定的 path 片段之后还未生成绝对路径,则会使用当前工作目录
// 生成的路径会被规范化,并且尾部的斜杠会被删除(除非路径被解析为根目录)
console.log(path.resolve('/目录1','/目录2','目录3')) // '/目录2/目录3' 因为 '目录3' 不是绝对路径,但 '/目录2' + '/' + '目录3' 是
console.log(path.resolve('/目录1/目录2', './目录3')) // '/目录1/目录2/目录3'
console.log(path.resolve('/目录1/目录2', '/目录3/目录4/')) // '/目录3/目录4'
console.log(path.resolve('目录1', '目录2/目录3/', '../目录4/文件.gif')) //'/目录A/目录B/目录1/目录2/目录4/文件.gif'
// 生成当前文件的绝对路径
console.log(path.resolve(__dirname,'index.js')) //C:\Users\Administrator\Desktop\NodeJs\index.js
- fs模块,用于文件的读写
读文件:fs.readFile(path[, options], callback)
。
path 参数是文件名或文件描述符。
options 参数是配置,如果没有指定字符编码,则返回原始的 buffer。如果 options 是字符串,则它指定字符编码:fs.readFile('/etc/passwd', 'utf8', callback);
callback 回调函数,回调会传入两个参数 (err, data),其中 data 是文件的内容。
let fs = require('fs')
// fs.readFile 读取文件的全部内容
fs.readFile('./a.txt', (err,data) => {
if (err) throw err;
console.log(data)
})
// a.txt内容 hello nodejs
// 打印出来是 <Buffer 68 65 6c 6c 6f 20 6e 6f 64 65 6a 73 20 20 0d 0a>
// 指定字符编码
fs.readFile('./a.txt','utf8', (err,data) => {
if (err) throw err;
console.log(data)
})
// hello nodejs
//不指定字符编码的话,也可以调用toString()方法,结果跟上边是一样的
fs.readFile('./a.txt', (err,data) => {
if (err) throw err;
console.log(data.toString())
})
fs.readFile() 函数会缓冲整个文件。 若要最小化内存成本,则尽可能选择流式(使用 fs.createReadStream())。
写文件:fs.writeFile(file, data[, options], callback)
fs.writeFile('b.txt', '哈哈', (err) => {
if (err) throw err;
})
// 运行之后,生成b.txt文件,内容是 哈哈
// 当我们修改哈哈为呵呵后再执行,b.txt文件内容变为了 呵呵
// 如果我们不想覆盖原本的内容,而是把新内容追加在旧的内容后边,只需要设置一个参数 {flag:"a"}
fs.writeFile('b.txt', '呵呵',{flag:"a"}, (err) => {
if (err) throw err;
})
- 上边的读写都是异步的,fs还有同步的读写方法,跟异步的区别就是没有了回调函数
let fs = require('fs')
let data = fs.readFileSync('a.txt')
console.log(data.toString()) //hello nodejs
fs.writeFileSync('b.text','我是同步的写入方法')
自定义模块
每一个nodejs文件就是一个模块,每一个模块就是一个nodejs文件,一般这个模块会返回一个对象,这个对象包含了这个模块的所有操作方法和属性;
自定义模块需要的三元素 exports
,module
,require
现在我们自己封装一个模块,mod.js
exports.a = 1;
exports.b = 2;
exports.c = d;
function d() {
console.log(a)
}
let e = 3;
然后我们在index.js里,通过require引入这个模块,并赋值给遍历mod
const mod = require('mod')
console.log(mod.a)
console.log(mod.b)
console.log(mod.c)
console.log(mod.d)
image.png
这个时候是会报错的,说找不到 mod模块,这主要是因为require的引入方式引起的
- 如果有路径就去路径里去找
- 如果没有路径就到node_modules里去找
- 如果都没有找到,再去node的按照目录里去找
所以,我们引入的时候,可以改为 require('./mod.js'),然后就可以正常执行了
如果我们不修改引入路径,把模块放入
node_modules
文件夹,有可以引入成功;module
,是批量导出的意思
// mod.js
module.exports = {
a:1,b:2
}
// index.js
const mod = require('./mod')
console.log(mod.a) // 1
console.log(mod.b) // 2
或者导出一个方法
// mod.js
module.exports = function () {
console.log('aaa')
}
// index.js
const mod = require('./mod')
mod() // aaa
也可以导出一个 class
// mod.js
module.exports = class {
constructor(name) {
this.name = name
}
show() {
console.log(this.name)
}
}
// index.js
const mod = require('./mod')
let p = new mod('andy')
p.show() // andy
重点:HTTP模块
- 大多数nodejs开发者都是冲着开发
web server
的目的选择了nodejs。正如官网所展示的,借助http模块,可以几行代码就搞定一个超迷你的web server。 - 在nodejs中,http可以说是最核心的模块
- 创建1个web服务器
const http = require('http')
http.createServer(() => {
console.log('我来了')
}).listen(8080)
image.png
createServer的参数事一个回调函数,这个回调函数正常情况下,是有两个参数的,response
,request
我们先看下response
的用法
const http = require('http')
http.createServer((req,res) => {
res.write('index')
res.end()
}).listen(8080)
image.png
const http = require('http')
http.createServer((req,res) => {
// res.write('index')
// res.end()
// 也可以省略 res.write()
// 直接写
res.end('index2')
}).listen(8080)
image.png
再来看request
的用法
const http = require('http')
http.createServer((req,res) => {
console.log(req.url)
}).listen(8080)
image.png
image.png
image.png
image.png
// 我们把之前学的串联起来
const http = require('http')
const fs = require('fs')
http.createServer((req, res) => {
// req.url 来判断我们要访问的东西
// fs读取到内容,然后读取到的内容通过respons返还给页面,包括响应码
fs.readFile(`${req.url}`, (err, data) => {
if (err) {
res.writeHead(404)
res.end('404 not found')
} else {
res.writeHead(200) // 有数据时 可不写 默认是200
res.end(data) // 有数据就返回给页面
}
})
}).listen(8888)
上面的写法,会导致页面上显示404 ,因为readFile的第一个参数我们没有写对路径,应该加./
const http = require('http')
const fs = require('fs')
http.createServer((req, res) => {
// req.url 来判断我们要访问的东西
fs.readFile(`./${req.url}`, (err, data) => {
if (err) {
res.writeHead(404)
res.end('404 not found')
} else {
res.writeHead(200) // 有数据时 可不写 默认是200
res.end(data) // 有数据就返回给页面
}
})
}).listen(8888)
image.png
网友评论