一、nodejs是什么
nodejs是基于V8引擎的js运行时环境
- 运行时环境:Node.js是基于Chrome V8引擎的JavaScript运行时
- 技术基础:构建在V8 JavaScript引擎之上
- 执行原理:通过嵌入V8引擎获得执行JavaScript代码的能力
二、nodejs和浏览器的区别
-
技术本质:
- 本质是C++应用程序,内部嵌入了V8引擎
- 提供JavaScript运行所需的完整环境
-
对比浏览器:
- 浏览器需要额外处理HTML/CSS渲染
- Node专注于系统级操作(文件、网络等)
v8引擎介绍
-
核心作用:
- 解析和执行JavaScript代码
- 独立运行或嵌入C++应用(如Chrome/Node)
-
执行流程:
- 代码→Tokens→AST→字节码→机器码
- 包含即时编译(JIT)优化机制
浏览器和Node.js架构区别
-
浏览器架构:
- 核心:Blink渲染引擎 + V8引擎
- 扩展:DOM/BOM API、浏览器事件循环
-
Node架构:
- 核心:V8引擎 + libuv
- 扩展:文件系统、网络IO等系统级API
我们来看一个单独的Node.js的架构图:
我们编写的JavaScript代码会经过V8引擎,再通过Node.js的Bindings,将任务放到Libuv的事件循环中;
| 知识点 | 核心内容 | 考试重点/易混淆点 | 难度系数 |
|---|---|---|---|
| Node.js 定义 | 基于 V8 引擎的 JavaScript 运行时环境,用于执行 JS 代码(文件读写、网络 IO 等)。 | Node.js ≠ 浏览器环境,无 DOM/BOM API,但提供 fs/net 等模块。 | ⭐⭐ |
| Node.js 架构 | 1. V8 引擎:解析执行 JS 代码; 2. libuv(C 语言库):处理异步 I/O、事件循环、线程池; 3. Node.js Binding:连接 JS 与底层系统调用。 | libuv 与 V8 分工:JS 逻辑由 V8 处理,系统级操作(如文件读写)由 libuv 调度。 | ⭐⭐⭐ |
| Node.js 应用场景 | 1. 前端工程化(Webpack/Vite); 2. 后端开发(Express/NestJS); 3. 工具链开发(CLI 工具)。 | 面试高频点:为何前端需要学 Node.js?(工程化依赖、BFF 层开发)。 | ⭐⭐ |
| Node.js 安装与管理 | 1. 直接安装 Node.js; 2. 使用 nvm 管理多版本切换。 | nvm 跨平台差异:Windows 用 nvm-windows,Mac/Linux 用原生 nvm。 | ⭐ |
| Node.js 运行 JS 代码 | 通过命令行 node filename.js 执行,无需浏览器环境。 | 与浏览器执行差异:全局对象为 global 而非 window。 | ⭐ |
| Node.js 输入输出 | 1. 控制台输出:console.log(); 2. 文件读写:fs.readFile()/fs.writeFile()。 | 异步回调风格 vs. fs.promises API(Promise 封装)。 | ⭐⭐ |
| Node.js 全局对象 | global、process(进程信息)、__dirname(当前路径)等。 | 易混淆点:setTimeout 属于 libuv 事件循环,非浏览器独有。 | ⭐⭐ |
| Node.js 与浏览器对比 | 1. 共同点:共用 V8 引擎、事件循环; 2. 差异:Node.js 无渲染引擎,但提供 系统级 API。 | 底层差异:浏览器用 Blink 渲染,Node.js 用 libuv 调度 I/O。 | ⭐⭐⭐ |
三、Node.js的应用场景
目前前端开发库以node包形式管理
-
现代开发模式:
- 不再手动下载并通过script标签引入
- 使用npm等工具自动管理依赖
- 示例:npm install lodash安装lodash库
-
包管理优势:
- 所有主流库都上传到npm仓库
- 简化依赖管理流程
- 自动处理版本控制和依赖关系
npm、yarn、pnpm工具成为前端开发使用最多的工具
-
主流工具:
- npm:Node.js内置的包管理工具
- yarn:Facebook开发的替代工具
- pnpm:更高效的包管理方案
-
使用方式:
- 安装命令:npm install
- 简写形式:npm i
- 添加开发依赖:npm add -D
四、 Node程序传递参数
| Node.js文件运行 | 通过node 文件名.js执行JavaScript文件 | 与浏览器执行环境的差异 |
|---|---|---|
| 控制台输出 | 使用console.log()输出内容 | 多种输出方法(console.clear/console.trace)的区别 |
| 程序参数输入 | 通过process.argv获取命令行参数 | 参数解析与数组索引关系([0]和[1]的特殊含义) |
-
process.argv: 获取命令行参数的数组,包含:
- 第0个元素:Node程序路径
- 第1个元素:当前执行JS文件路径
- 第2个及以后元素:用户传入参数
1. 全局对象
global对象
-
- 与浏览器的区别:在Node.js环境中没有window对象,执行console.log(window)会报错"window is not defined"
- 替代对象:Node.js中使用global作为全局对象,相当于浏览器中的window对象
| 全局对象对比 | global对象类比浏览器中的window对象 | 关键区别:var声明不会自动挂载到global |
|---|---|---|
| 特殊全局对象 | __dirname(当前目录)、__filename(含文件名路径) | 路径处理时的常见应用场景 |
| 进程对象 | process包含进程信息、环境变量、命令行参数 | process.argv参数解析的实际应用 |
| 定时器方法 | setTimeout/setInterval/setImmediate | 执行顺序:nextTick vs setImmediate顺序不一定 |
| 模块系统 | module/exports/require(后续讲解重点) | CommonJS模块化规范实现原理 |
| 标准化全局访问 | globalThis作为跨环境的全局对象统一标识符 | 兼容浏览器和Node环境的写法 |
|---|
五、模块化开发
什么是模块化
-
核心目标:将程序划分成独立的小结构(模块),每个模块有自己的作用域和逻辑代码
-
关键特性:
- 模块内部定义的变量不会影响其他模块
- 可以通过导出机制暴露模块内容供其他模块使用
- 可以通过导入机制使用其他模块的内容
-
开发过程:按照这种结构划分开发程序的过程就是模块化开发
CommonJS规范和Node关系
导出
导入
导出与导入原理
- exports本质:exports是一个空对象,通过添加属性实现导出功能
- 内存机制:exports保存的是模块内部对象的引用地址,require获取的是同一个对象的引用
- 引用赋值原理:require通过各种查找方式找到exports对象后,将该对象的引用赋值给导入变量
| 知识点 | 核心内容 | 考试重点/易混淆点 |
|---|---|---|
| CommonJS规范 | Node.js中通过exports对象导出模块,require函数导入模块 | exports |
| 模块导出本质 | 导出操作本质是引用赋值,导入导出指向同一内存对象 | 修改导出对象属性会影响所有导入方 |
| 动态修改验证 | 通过setTimeout演示导出对象属性被修改后,导入方获取的是最新值 | 两处代码操作的是同一内存对象 |
| 模块化原理 | require返回的是模块内部exports对象的内存地址引用 | 与普通变量赋值的本质差异 |
| 对象属性导出 | 通过exports.属性名=值方式添加导出属性 | 未添加属性前exports是空对象 |
平常常用的moudle.export={},是新创建了一个对象了