Node.js(一) 基础语法

165 阅读7分钟

「本文正在参与技术专题征文Node.js进阶之路,点击查看详情

什么是 Node.js

Node.js 一个基于 Chrome V8 引擎的 JavaScript 运行环境

Node.js 是支持所有 ECMAScript 语法规范的, 所以所有的 js 基础和高级语法都可以使用

JavaScript 运行环境

  • 浏览器是 JavaScript 客户端的运行环境
  • Node.jsJavaScript 服务端的运行环境

Node 中的模块化

Node 中,规定每个 JS 文件都是一个小模块。一个项目由许许多多的小模块( JS 文件)组合而成。

模块化

什么是模块化

模块化,就是把一个大的文件拆分成若干小文件,而且还能把小文件通过特定的语法组合到一起的实现过程。

模块化优点

Node 中模块化的优势:

  • 更利于维护
    • 例 : 项目后期需要对某个模块(登录模块)进行修改, 其他模块不会受到影响
  • 更好的复用性
    • 例 : 公共的业务逻辑进行封装, 复用更加方便

Node 模块化规范

CommonJS : Node中的模块化使用的是CommonJS规范。

CommonJS 模块的特点

  • 模块内的变量不会污染全局, 模块内的代码都运行在模块内的作用域
  • 模块可以多次加载,但是只会在第一次加载时运行一次,然后运行结果就被缓存了,以后再加载,就直接读取缓存结果。要想让模块再次运行,必须清除缓存。
  • 同步加载, 模块加载的顺序是同步加载,按照使用的顺序加载, 只有当前加载完成,才能执行后面的操作

CommonJS 使用模块的语法

  • 通过require函数进行导入
    • const 模块名 = require('模块路径')
  • 通过export或者module.exports导出
    • module.exports = {模块内的变量}

模块的分类

  • 自定义模块
    • Node.JS 中,创建的 js 文件都是自定义模块
  • 内置模块( 又叫核心模块 )
    • Node.JS 中, 自带的模块
    • 内置模块的导入语法: const 模块名 = require('模块名')
  • 第三方模块
    • 下载第三方文件 , 导入后使用

自定义模块

Node.JS 中每个 JS 文件都是一个自定义模块,并且具有模块作用域,也就是在一个模块中创建的变量、常量、函数等等一切,都只能在当前模块中使用。

共享(导出/暴露)内容

共享内容给其他模块用,需要使用 module.exports 导出内容。

  • moduleNode.JS 中的一个全局对象,对象包含当前模块的详细信息。
  • module.exports 是模块的出口,就是导出内容用的,默认值是 {}

代码实例

let age = 18
let name = '响响'
let fn = x => x 
// 导出age、name、fn给其他模块使用
module.exports = { age, name, square }

使用自定义模块

如果需要使用上述模块导出的内容,可以使用 require() 加载(导入)

  • let 模块名 = require('模块路径')
  • 注意: 加载自定义模块,必须使用路径,不能省略前缀(例:./)但是可以省略后缀(例:'.js')

代码实例

let 模块名 = require('上述文件路径')
console.log(模块名); // { age: 18, name: '响响', fn: X => X }

内置模块

内置模块是 Node.js 平台自带的 API (功能模块)。也叫做核心模块。

注意: 加载内置模块,不能写路径 , 直接使用模块名

常用的内置模块

  • path 模块 : 路径处理模块
  • fs 模块 : 文件处理模块
  • querystring模块 : 查询字符串处理模块
  • http模块 : http服务器处理模块

1 . path 模块

path 是 Node 本身提供的 API,专门用来处理路径。

使用方法

  • 加载模块 let path = require('path')

path模块中的方法

  • path.basename(参数1,参数2) : 返回 path 的最后一部分(文件名)
    • 第一参数是路径, 第二个参数是扩展名
    • 传一个参数, 返回 文件名.扩展名
    • 传两个参数, 返回 文件名
  • path.dirname(路径) : 返回目录名
  • path.extname(路径) : 返回路径中文件的扩展名(包含.)
   // extname -- 获取文件后缀
   console.log(path.extname('index.html')); // .html
   console.log(path.extname('index.coffee.md')); // .md
  • path.format(对象) : 将一个对象格式化为一个路径字符串
  • path.join(__dirname,文件路径) : 拼接路径
    • __dirname 动态获取文件所在文件夹(业务中常用)
    • __filename 动态获取文件位置
  • path.parse(路径) : 把路径字符串解析成对象的格式
   // join -- 智能拼接路径
   // console.log(path.join('a', 'b', 'c')); // a/b/c
   
   // console.log(path.join('a', 'b', 'c', 'index.css')); // a/b/c/index.css
   
   // a里面有b,b里面有../c,言外之意,c和b同级。
   // console.log(path.join('a', 'b', '../c', 'index.js')); // a/c/index.js
   
   // __dirname 永远表示当前js文件的绝对路径
   console.log(path.join(__dirname, 'css', 'demo.css')); // /Users/code/css/demo.css

2 . fs 模块

fs (file system) : 文件系统模块 , 可以实现对 文件、文件夹的操作

fs模块的方法

  • fs.readFile : 读取文件的方法, 异步操作
    • fs.readFile('文件路径', '编码集', (err, data)=>{}}
    • 读取失败 err 为对象, dataundefined;
    • 读取成功 errnull, data 是读取到的字符串;
    • 所有的错误对象都有两个属性: name 和 message (错误信息)
    • 注意点:
      • 错误优先原则 err 参数在前面
      • 纯文本一般设置编码集,但是如果是 图片/音频/视频... 特定的软件,用的定方式打开
  • fs.writeFile : 写入文件内容, 写入方法也是异步
    • fs.writeFile('文件路径', '我是刚刚写入的内容', err => {})
    • 写入成功,errnull ; 写入失败,err为错误对象;
    • 注意 :
      1. 文件不存才会创建文件,文件存在会覆盖原有内容 (appendFile不会覆盖,会追加)
      2. 文件夹如果不存在就报错!
  • fs.appendFile : 写入文件内容 , 不会覆盖原有内容
    • fs.appendFile('文件路径', '我是刚刚写入的内容', err => {})
  • fs.access : 判断一个文件是否存在/可读/可写
    • fs.access('文件路径', 参数2, err => {})
    • 参数2可选;
      • fs.constants.F_OK : 或不填,表示判断文件是否存在;
      • fs.constants.R_OK : 表示判断文件是否可读;
      • fs.constants.W_OK : 表示文件是否可写
    • err是对象,就说明文件不存在;
    • errnull,就说明文件存在;

querystring模块

查询字符串处理模块

3 . querystring 模块两个方法

  • querystring.parse : 字符串转换为对象, 自带解码
// parse -- 将查询字符串解析成JS对象
console.log(querystring.parse('id=1&name=zs&age=20')) 
// { id: '1', name: 'zs', age: '20' }
  • querystring.stringify : 转换为字符串, 自带编码
// stringify -- 将JS对象转成查询字符串
console.log(querystring.stringify({ id: '1', name: 'zs', age: '20' }));
// id=1&name=zs&age=20

4 . http 模块

http是一个系统模块,让我们能够通过简单的流程创建一个 Web 服务器

使用http模块搭建Web服务器

创建 Web 服务器的步骤

  • 导入 http 核心模块
  • 创建 server 对象(server 对象负责建立连接,接收数据)
  • 注册 request 事件,当浏览器发送请求到服务器执行,设置处理请求的函数
  • 监听端口(==这个步骤也可以放到注册request事件之前==)
  • 当服务器接收到浏览器的请求后,如果没有做出响应,浏览器会等待
  • 服务器的最终目的是要根据请求做出响应,肯定要调用 res.end() 方法。
// 导入 http 模块
const http = require('http');

// 创建一个服务器对象
const server = http.createServer();

// 监听事件
server.on('request', (request, response) => {
    // 响应给客户端信息 - 别用标签和汉字
    response.end('hello Mr Lv!');
})

// 启动服务
server.listen(8888, () => {
    console.log('程序已经启动,请访问: http://127.0.0.1:8888 ');
});

request(req) 和 response(res) 参数

上述代码的格式基本固定。只有 请求事件 的处理函数需要说明一下。

当收到浏览器的请求后,会触发request事件,事件处理函数有两个形式参数 request 和 response。

server.on('request', (request, response) => {
  // 设置响应状态码
  response.statusCode = 200;
  // 设置响应头
  response.setHeader('Content-Type', 'text/plain; charset=utf-8');
  // 设置响应体
  response.end('hello,欢迎访问服务器,这是服务器给你的回应');
});
  • 形参 request

    • 通过 request 对象,可以获取到 请求相关信息。
    • request.url 获取请求行中的路径
    • request.method 获取请求行中的请求方法
    • request.headers 获取请求头
  • 形参 response

    • 做出响应,需要使用 response 对象。
    • statusCode 设置响应状态码,必须在 end方法前调用
    • response.setHeader() 设置响应头,比如设置响应体的编码,必须在end方法前调用
    • response.end() 把响应报文(响应行、响应头、响应体)发送给浏览器,通俗的讲就是做出响应。
      • end() 调用,表示做出响应
      • end() 调用后,不能再设置响应状态码和响应头
      • end() 的参数表示响应结果;只能填字符串