Node.js让JavaScript脱离了浏览器环境,可以直接在操作系统上运行,进而编写服务端应用、命令行工具和自动化脚本。很多人第一次接触Node.js时,容易停留在“能跑就行”的阶段,忽略了模块加载、异步回调、路径处理这些基础细节。下面用8个示例把核心知识点串起来,每个示例都给出风格的简短代码,并补充实际项目中的经验判断。
示例1:用console.log输出第一条消息
第一个Node.js程序通常从控制台输出开始:
console.log('Hello Tpoint Tech');
输出:
Hello Tpoint Tech
console.log()把内容写到标准输出流。在Node.js里它不只是调试工具,命令行工具的状态提示、脚本执行进度、CI日志都依赖它。实际项目中建议把业务日志和调试输出分开,生产环境用console.error输出错误,避免所有信息混在一起。
示例2:算术运算与数值类型
Node.js延续了JavaScript的数值模型,所有数字都是Number类型:
const firstNumber = 20;
const secondNumber = 30;
const addition = firstNumber + secondNumber;
console.log(addition);
输出:
50
这段代码看似简单,但有一个容易踩的坑:JavaScript没有整数和浮点数的区分,0.1+0.2不等于0.3。如果项目涉及金额计算,不要直接用浮点数做加减,建议以“分”为单位存整数,或者引入decimal库处理。const声明的是常量绑定,不是值不可变,对对象类型仍然可以修改属性,这一点在团队协作中经常被误解。
示例3:变量声明与输出格式
变量用来存储程序运行过程中需要反复访问的数据:
const name = "John";
const age = 25;
console.log("Name:", name);
console.log("Age:", age);
输出:
Name: John
Age: 25
console.log支持多参数输出,中间会自动加空格。项目开发中我更倾向于用模板字符串拼接,而不是多参数:
console.log(`Name: ${name}, Age: ${age}`);
原因是一次输出一条完整信息,日志采集工具解析起来更稳定。多参数在对象和字符串混合时,格式容易变得不可控。
示例4:if-else条件判断
根据学生分数判断是否及格:
const marks = 85;
if (marks >= 40) {
console.log("Pass");
} else {
console.log("Fail");
}
输出:
Pass
条件判断本身不复杂,但项目里常见的问题是边界条件写错。比如“大于等于40算通过”和“大于40算通过”在考试系统中结果不同。建议把阈值抽成常量:
const PASS_MARK = 40;
if (marks >= PASS_MARK) { ... }
这样后续调整标准时只改一处,避免散落在多个文件里。
示例5:函数封装与复用
函数把一段逻辑组织成可复用的单元:
function greet(name) {
return `Hello, ${name}!`;
}
console.log(greet("John"));
输出:
Hello, John!
这里用的是函数声明,存在变量提升。实际项目中更推荐箭头函数或函数表达式,因为提升行为在大型代码库里容易造成“函数在哪定义”的困惑。greet只做一件事——拼接待返回的字符串,没有副作用,这种纯函数最容易测试和维护。
示例6:用fs模块创建文件
Node.js内置fs模块用于文件系统操作:
const fs = require('fs');
fs.writeFile('sample.txt', 'Welcome to Tpoint Tech', (err) => {
if (err) {
console.log(err);
return;
}
console.log('File created successfully.');
});
输出:
File created successfully.
fs.writeFile是异步方法,回调里第一个参数是错误对象。这里有一个实际踩坑经历:早期项目里直接用fs.writeFileSync写日志,QPS一高就阻塞事件循环,接口响应时间明显上升。后来改成异步写入,并配合写入队列,才把问题压下去。如果只是脚本初始化配置,同步方法可以接受;如果是请求链路中的文件操作,优先用异步版本或fs.promises。
示例7:用path模块获取当前文件名
path模块处理跨平台的路径问题:
const path = require('path');
console.log(path.basename(__filename));
输出:
index.js
__filename是当前模块的完整路径,path.basename()从中提取文件名。为什么要用path而不是字符串截取?因为Windows用反斜杠、Linux用斜杠,手写split('/')在Windows上会直接失效。path.join、path.resolve也是项目里高频使用的方法,拼路径时不要用字符串加号。
示例8:用os模块读取系统信息
os模块提供操作系统层面的信息:
const os = require('os');
console.log(os.platform());
console.log(os.arch());
输出:
win32
x64
os.platform()返回运行平台,os.arch()返回CPU架构。这类信息常用于环境判断,比如根据平台决定调用哪个二进制文件。实际项目中不建议把平台判断写死在业务代码里,可以封装成配置加载层,让业务逻辑只关心“当前是什么环境”,而不是到处写if(os.platform()==='win32')。
本节课程知识要点
-
console.log适合快速验证和命令行输出,生产日志建议区分级别。 -
JavaScript数值只有Number类型,金额计算避免直接浮点运算。
-
const绑定不可重新赋值,但对象属性仍可修改。 -
条件判断的阈值抽成常量,减少边界错误。
-
纯函数优先,函数职责单一,便于测试。
-
文件操作区分同步与异步,请求链路中避免同步阻塞。
-
路径拼接统一用
path模块,不要手动拼字符串。 -
系统信息读取适合放在环境配置层,不要散落在业务代码中。
课后总结
很多Node.js初学者把8个示例跑通后,就急着上Express或Koa写接口。但真正进入项目后,出问题最多的往往不是框架用法,而是文件路径、异步顺序、环境判断这些基础环节。我的建议是:先把fs、path、os这三个内置模块用熟,再去看框架源码,会顺畅很多。框架解决的是路由和中间件组织,底层能力还是这些内置模块在支撑。
2026年的Node.js生态里,ESM已经逐渐成为主流,require()和import混用的问题需要提前注意。如果新项目没有历史包袱,可以直接从ESM起步,避免后续迁移成本。