Node.js 全局对象与全局变量
章节介绍
Node.js 提供了许多全局对象和全局变量,这些对象和变量可以在任何模块中直接使用,无需显式导入。理解这些全局对象对于编写高效的 Node.js 应用程序至关重要。本教程将详细介绍 Node.js 的全局对象和全局变量,帮助您掌握 Node.js 的运行环境。
核心知识点
全局对象概述
Node.js 的全局对象类似于浏览器中的 window 对象,但有一些重要的区别:
- global 对象:Node.js 的全局命名空间
- process 对象:提供当前 Node.js 进程的信息和控制
- console 对象:用于打印输出和调试
- 定时器函数:setTimeout、setInterval、setImmediate 等
- Buffer 类:用于处理二进制数据
全局对象结构:
┌─────────────────────────────────────┐
│ global 对象 │
├─────────────────────────────────────┤
│ ┌─────────────┐ ┌──────────────┐ │
│ │ process │ │ console │ │
│ └─────────────┘ └──────────────┘ │
│ ┌─────────────┐ ┌──────────────┐ │
│ │ setTimeout │ │ setInterval │ │
│ └─────────────┘ └──────────────┘ │
│ ┌─────────────┐ ┌──────────────┐ │
│ │ Buffer │ │ __dirname │ │
│ └─────────────┘ └──────────────┘ │
│ ┌─────────────┐ ┌──────────────┐ │
│ │ __filename │ │ require() │ │
│ └─────────────┘ └──────────────┘ │
└─────────────────────────────────────┘global 对象
global 对象是 Node.js 的全局命名空间,所有全局变量和函数都是 global 对象的属性。
// 访问 global 对象
console.log(global);
// 在全局作用域中声明的变量会成为 global 的属性
global.myGlobal = '全局变量';
console.log(global.myGlobal); // 全局变量
// 等同于直接声明(不推荐)
myGlobal2 = '另一个全局变量';
console.log(global.myGlobal2); // 另一个全局变量
// 检查全局变量是否存在
if (global.myGlobal) {
console.log('myGlobal 存在');
}
// 遍历 global 对象的所有属性
for (const key in global) {
console.log(key);
}process 对象
process 对象提供当前 Node.js 进程的信息和控制,是一个非常重要的全局对象。
进程信息
// 获取进程 ID
console.log('进程 ID:', process.pid);
// 获取 Node.js 版本
console.log('Node.js 版本:', process.version);
console.log('V8 版本:', process.versions.v8);
// 获取平台信息
console.log('操作系统:', process.platform); // win32, darwin, linux
console.log('CPU 架构:', process.arch); // x64, arm, ia32
// 获取执行参数
console.log('执行路径:', process.execPath);
console.log('当前工作目录:', process.cwd());
console.log('脚本路径:', process.argv[0]);
console.log('命令行参数:', process.argv.slice(2));
// 获取环境变量
console.log('环境变量:', process.env);
console.log('PATH:', process.env.PATH);
console.log('HOME:', process.env.HOME);进程控制
// 退出进程
process.exit(0); // 正常退出
process.exit(1); // 异常退出
// 设置退出代码
process.exitCode = 1;
// 监听退出事件
process.on('exit', (code) => {
console.log(`进程退出,退出代码:${code}`);
});
// 发送信号
process.kill(process.pid, 'SIGTERM');
// 设置进程标题
process.title = 'My Node.js App';
console.log('进程标题:', process.title);
// 改变工作目录
process.chdir('/path/to/directory');
console.log('新的工作目录:', process.cwd());
// 设置用户 ID 和组 ID(需要 root 权限)
// process.setuid(1000);
// process.setgid(1000);内存和 CPU 信息
// 内存使用情况
const memoryUsage = process.memoryUsage();
console.log('内存使用情况:');
console.log(' RSS(常驻内存):', (memoryUsage.rss / 1024 / 1024).toFixed(2), 'MB');
console.log(' 堆总大小:', (memoryUsage.heapTotal / 1024 / 1024).toFixed(2), 'MB');
console.log(' 堆已使用:', (memoryUsage.heapUsed / 1024 / 1024).toFixed(2), 'MB');
console.log(' 外部内存:', (memoryUsage.external / 1024 / 1024).toFixed(2), 'MB');
// CPU 使用情况
const cpuUsage = process.cpuUsage();
console.log('CPU 使用情况:');
console.log(' 用户态 CPU 时间:', cpuUsage.user / 1000, 'ms');
console.log(' 内核态 CPU 时间:', cpuUsage.system / 1000, 'ms');
// 获取 CPU 信息
console.log('CPU 信息:', process.cpuUsage());标准输入输出
// 标准输入
process.stdin.setEncoding('utf8');
process.stdin.on('data', (data) => {
console.log('输入:', data.trim());
});
// 标准输出
process.stdout.write('标准输出:Hello World\n');
// 标准错误
process.stderr.write('标准错误:Error message\n');
// 重定向输出
const fs = require('fs');
const output = fs.createWriteStream('output.log');
process.stdout.write = output.write.bind(output);
console.log('这条消息会被写入文件');进程事件
// 监听未捕获的异常
process.on('uncaughtException', (error) => {
console.error('未捕获的异常:', error);
process.exit(1);
});
// 监听未处理的 Promise 拒绝
process.on('unhandledRejection', (reason, promise) => {
console.error('未处理的 Promise 拒绝:', reason);
});
// 监听警告
process.on('warning', (warning) => {
console.warn('警告:', warning.name, warning.message);
});
// 监听信号
process.on('SIGINT', () => {
console.log('收到 SIGINT 信号,准备退出...');
process.exit(0);
});
// 监听消息(用于进程间通信)
process.on('message', (message) => {
console.log('收到消息:', message);
});
// 发送消息
if (process.send) {
process.send({ type: 'greeting', data: 'Hello' });
}console 对象
console 对象用于向标准输出和标准错误流打印信息。
基本输出方法
// 打印到标准输出
console.log('普通日志');
console.log('格式化日志:%s, %d, %j', '字符串', 100, { key: 'value' });
// 打印到标准错误
console.error('错误信息');
console.error('错误详情:', new Error('Something went wrong'));
// 打印警告
console.warn('警告信息');
// 打印信息
console.info('信息日志');
// 打印调试信息
console.debug('调试信息');格式化输出
// 格式化占位符
console.log('字符串:%s', 'Hello');
console.log('数字:%d', 42);
console.log('浮点数:%.2f', 3.14159);
console.log('JSON:%j', { name: '张三', age: 25 });
console.log('对象:%o', { name: '张三', age: 25 });
// 颜色输出
console.log('\x1b[31m红色文本\x1b[0m');
console.log('\x1b[32m绿色文本\x1b[0m');
console.log('\x1b[33m黄色文本\x1b[0m');
console.log('\x1b[34m蓝色文本\x1b[0m');
// 使用 ANSI 颜色代码
const colors = {
reset: '\x1b[0m',
red: '\x1b[31m',
green: '\x1b[32m',
yellow: '\x1b[33m',
blue: '\x1b[34m'
};
console.log(`${colors.red}错误信息${colors.reset}`);
console.log(`${colors.green}成功信息${colors.reset}`);高级输出方法
// 打印表格
console.table([
{ name: '张三', age: 25, city: '北京' },
{ name: '李四', age: 30, city: '上海' },
{ name: '王五', age: 28, city: '广州' }
]);
// 打印堆栈跟踪
console.trace('堆栈跟踪:');
// 计时
console.time('timer');
setTimeout(() => {
console.timeEnd('timer'); // timer: 1000.123ms
}, 1000);
// 计时标签
console.time('loop');
for (let i = 0; i < 1000000; i++) {
// 循环
}
console.timeEnd('loop');
// 断言
console.assert(1 === 1, '1 等于 1');
console.assert(1 === 2, '1 不等于 2'); // AssertionError: 1 不等于 2
// 分组输出
console.group('分组 1');
console.log('消息 1');
console.log('消息 2');
console.groupEnd();
console.groupCollapsed('折叠分组');
console.log('消息 3');
console.log('消息 4');
console.groupEnd();定时器函数
Node.js 提供了多种定时器函数,用于延迟执行或重复执行代码。
setTimeout
// 基本使用
setTimeout(() => {
console.log('1 秒后执行');
}, 1000);
// 带参数
function greet(name) {
console.log(`你好,${name}!`);
}
setTimeout(greet, 1000, '张三');
// 清除定时器
const timerId = setTimeout(() => {
console.log('这条消息不会被打印');
}, 1000);
clearTimeout(timerId);
// 嵌套定时器
setTimeout(() => {
console.log('第一步');
setTimeout(() => {
console.log('第二步');
setTimeout(() => {
console.log('第三步');
}, 1000);
}, 1000);
}, 1000);setInterval
// 基本使用
let count = 0;
const intervalId = setInterval(() => {
count++;
console.log(`计数:${count}`);
if (count >= 5) {
clearInterval(intervalId);
}
}, 1000);
// 带参数
function logMessage(message) {
console.log(message);
}
setInterval(logMessage, 1000, '定时消息');
// 清除定时器
const timerId = setInterval(() => {
console.log('每秒执行一次');
}, 1000);
setTimeout(() => {
clearInterval(timerId);
}, 5000);setImmediate
// 在 I/O 事件回调之后立即执行
setImmediate(() => {
console.log('setImmediate 执行');
});
// 与 setTimeout 的区别
console.log('开始');
setTimeout(() => {
console.log('setTimeout');
}, 0);
setImmediate(() => {
console.log('setImmediate');
});
console.log('结束');
// 执行顺序可能是:
// 开始
// 结束
// setTimeout
// setImmediate
// 或者在 I/O 回调中
const fs = require('fs');
fs.readFile(__filename, () => {
setImmediate(() => {
console.log('setImmediate 在 I/O 回调中');
});
setTimeout(() => {
console.log('setTimeout 在 I/O 回调中');
}, 0);
});process.nextTick
// 在当前操作完成后立即执行
console.log('开始');
process.nextTick(() => {
console.log('process.nextTick');
});
console.log('结束');
// 执行顺序:
// 开始
// 结束
// process.nextTick
// 与 setImmediate 的区别
console.log('开始');
process.nextTick(() => {
console.log('nextTick 1');
process.nextTick(() => {
console.log('nextTick 2');
});
});
setImmediate(() => {
console.log('setImmediate 1');
setImmediate(() => {
console.log('setImmediate 2');
});
});
// 执行顺序:
// 开始
// nextTick 1
// nextTick 2
// setImmediate 1
// setImmediate 2其他全局变量
// __dirname:当前模块的目录名
console.log('__dirname:', __dirname);
// __filename:当前模块的文件名
console.log('__filename:', __filename);
// require:引入模块的函数
const fs = require('fs');
// module:当前模块的引用
console.log('当前模块:', module.id);
// exports:当前模块的导出对象
exports.myFunction = function() {
console.log('我的函数');
};
// Buffer:Buffer 类
const buffer = Buffer.from('Hello World');
console.log(buffer.toString());
// URL 和 URLSearchParams(全局可用)
const url = new URL('https://example.com/path?query=value');
console.log(url.hostname);
console.log(url.searchParams.get('query'));实用案例分析
案例 1:命令行工具
创建一个命令行工具,解析命令行参数并执行相应操作。
// cli.js
const fs = require('fs');
const path = require('path');
function printHelp() {
console.log(`
使用方法:
node cli.js [命令] [参数]
命令:
help 显示帮助信息
create <name> 创建新文件
read <name> 读取文件内容
delete <name> 删除文件
list 列出当前目录的文件
version 显示版本信息
示例:
node cli.js create test.txt
node cli.js read test.txt
node cli.js delete test.txt
node cli.js list
`);
}
function createFile(name) {
const filePath = path.join(process.cwd(), name);
try {
fs.writeFileSync(filePath, 'Hello World');
console.log(`文件 ${name} 创建成功`);
} catch (error) {
console.error(`创建文件失败:${error.message}`);
process.exit(1);
}
}
function readFile(name) {
const filePath = path.join(process.cwd(), name);
try {
const content = fs.readFileSync(filePath, 'utf8');
console.log(`文件 ${name} 的内容:`);
console.log(content);
} catch (error) {
console.error(`读取文件失败:${error.message}`);
process.exit(1);
}
}
function deleteFile(name) {
const filePath = path.join(process.cwd(), name);
try {
fs.unlinkSync(filePath);
console.log(`文件 ${name} 删除成功`);
} catch (error) {
console.error(`删除文件失败:${error.message}`);
process.exit(1);
}
}
function listFiles() {
const dir = process.cwd();
try {
const files = fs.readdirSync(dir);
console.log('当前目录的文件:');
files.forEach(file => {
const filePath = path.join(dir, file);
const stats = fs.statSync(filePath);
const type = stats.isDirectory() ? '目录' : '文件';
console.log(` ${file} (${type})`);
});
} catch (error) {
console.error(`列出文件失败:${error.message}`);
process.exit(1);
}
}
function showVersion() {
console.log('CLI 工具版本:1.0.0');
console.log(`Node.js 版本:${process.version}`);
}
function main() {
const args = process.argv.slice(2);
if (args.length === 0) {
printHelp();
return;
}
const command = args[0];
const params = args.slice(1);
switch (command) {
case 'help':
printHelp();
break;
case 'create':
if (params.length === 0) {
console.error('错误:请指定文件名');
process.exit(1);
}
createFile(params[0]);
break;
case 'read':
if (params.length === 0) {
console.error('错误:请指定文件名');
process.exit(1);
}
readFile(params[0]);
break;
case 'delete':
if (params.length === 0) {
console.error('错误:请指定文件名');
process.exit(1);
}
deleteFile(params[0]);
break;
case 'list':
listFiles();
break;
case 'version':
showVersion();
break;
default:
console.error(`未知命令:${command}`);
printHelp();
process.exit(1);
}
}
main();案例 2:定时任务管理器
创建一个定时任务管理器,可以添加、删除和执行定时任务。
// task-scheduler.js
class TaskScheduler {
constructor() {
this.tasks = new Map();
this.taskId = 0;
}
addTask(fn, delay, ...args) {
const id = ++this.taskId;
const timerId = setTimeout(() => {
try {
fn(...args);
this.tasks.delete(id);
console.log(`任务 ${id} 执行完成`);
} catch (error) {
console.error(`任务 ${id} 执行失败:`, error);
this.tasks.delete(id);
}
}, delay);
this.tasks.set(id, {
id,
fn,
delay,
args,
timerId,
createdAt: new Date()
});
console.log(`任务 ${id} 已添加,将在 ${delay}ms 后执行`);
return id;
}
addRecurringTask(fn, interval, ...args) {
const id = ++this.taskId;
const timerId = setInterval(() => {
try {
fn(...args);
console.log(`周期性任务 ${id} 执行完成`);
} catch (error) {
console.error(`周期性任务 ${id} 执行失败:`, error);
}
}, interval);
this.tasks.set(id, {
id,
fn,
interval,
args,
timerId,
createdAt: new Date(),
recurring: true
});
console.log(`周期性任务 ${id} 已添加,每 ${interval}ms 执行一次`);
return id;
}
removeTask(id) {
const task = this.tasks.get(id);
if (task) {
if (task.recurring) {
clearInterval(task.timerId);
} else {
clearTimeout(task.timerId);
}
this.tasks.delete(id);
console.log(`任务 ${id} 已移除`);
return true;
}
return false;
}
listTasks() {
console.log('当前任务列表:');
if (this.tasks.size === 0) {
console.log(' 没有任务');
return;
}
this.tasks.forEach((task, id) => {
const type = task.recurring ? '周期性' : '一次性';
const time = task.delay || task.interval;
console.log(` 任务 ${id}:${type},${time}ms`);
});
}
clearAll() {
this.tasks.forEach((task, id) => {
if (task.recurring) {
clearInterval(task.timerId);
} else {
clearTimeout(task.timerId);
}
});
this.tasks.clear();
console.log('所有任务已清除');
}
}
// 使用示例
const scheduler = new TaskScheduler();
// 添加一次性任务
scheduler.addTask(() => {
console.log('任务 1:发送邮件');
}, 2000);
scheduler.addTask((name) => {
console.log(`任务 2:欢迎 ${name}`);
}, 3000, '张三');
// 添加周期性任务
scheduler.addRecurringTask(() => {
console.log('周期性任务:检查系统状态');
}, 5000);
scheduler.addRecurringTask(() => {
console.log('周期性任务:备份数据');
}, 10000);
// 列出任务
scheduler.listTasks();
// 移除任务
setTimeout(() => {
const taskId = 2;
scheduler.removeTask(taskId);
console.log(`\n移除任务 ${taskId} 后:`);
scheduler.listTasks();
}, 4000);
// 清除所有任务
setTimeout(() => {
console.log('\n清除所有任务:');
scheduler.clearAll();
}, 15000);案例 3:进度条显示
创建一个进度条显示工具,用于显示长时间运行任务的进度。
// progress-bar.js
class ProgressBar {
constructor(total, options = {}) {
this.total = total;
this.current = 0;
this.width = options.width || 40;
this.completeChar = options.completeChar || '=';
this.incompleteChar = options.incompleteChar || '-';
this.showPercent = options.showPercent !== false;
this.showTime = options.showTime !== false;
this.startTime = Date.now();
}
update(current) {
this.current = current;
this.render();
}
increment() {
this.current++;
this.render();
}
render() {
const percent = this.current / this.total;
const completed = Math.floor(this.width * percent);
const incomplete = this.width - completed;
const bar = this.completeChar.repeat(completed) +
this.incompleteChar.repeat(incomplete);
let output = `\r[${bar}]`;
if (this.showPercent) {
output += ` ${(percent * 100).toFixed(1)}%`;
}
if (this.showTime) {
const elapsed = Date.now() - this.startTime;
const remaining = this.current > 0
? (elapsed / this.current) * (this.total - this.current)
: 0;
output += ` | 已用:${this.formatTime(elapsed)} | 剩余:${this.formatTime(remaining)}`;
}
process.stdout.write(output);
if (this.current >= this.total) {
process.stdout.write('\n');
}
}
formatTime(ms) {
const seconds = Math.floor(ms / 1000);
const minutes = Math.floor(seconds / 60);
const hours = Math.floor(minutes / 60);
if (hours > 0) {
return `${hours}h ${minutes % 60}m ${seconds % 60}s`;
} else if (minutes > 0) {
return `${minutes}m ${seconds % 60}s`;
} else {
return `${seconds}s`;
}
}
}
// 使用示例
const total = 100;
const progressBar = new ProgressBar(total, {
width: 50,
showPercent: true,
showTime: true
});
console.log('开始处理...');
let current = 0;
const interval = setInterval(() => {
current += Math.floor(Math.random() * 5) + 1;
if (current >= total) {
current = total;
clearInterval(interval);
}
progressBar.update(current);
}, 100);代码示例
示例 1:系统信息监控
// system-monitor.js
function printSystemInfo() {
console.log('=== 系统信息 ===');
// 进程信息
console.log('\n进程信息:');
console.log(' 进程 ID:', process.pid);
console.log(' Node.js 版本:', process.version);
console.log(' 平台:', process.platform);
console.log(' 架构:', process.arch);
console.log(' 工作目录:', process.cwd());
// 内存信息
const memory = process.memoryUsage();
console.log('\n内存使用:');
console.log(' RSS:', (memory.rss / 1024 / 1024).toFixed(2), 'MB');
console.log(' 堆总大小:', (memory.heapTotal / 1024 / 1024).toFixed(2), 'MB');
console.log(' 堆已使用:', (memory.heapUsed / 1024 / 1024).toFixed(2), 'MB');
console.log(' 外部内存:', (memory.external / 1024 / 1024).toFixed(2), 'MB');
// CPU 信息
const cpu = process.cpuUsage();
console.log('\nCPU 使用:');
console.log(' 用户态:', (cpu.user / 1000000).toFixed(2), 's');
console.log(' 内核态:', (cpu.system / 1000000).toFixed(2), 's');
// 环境变量
console.log('\n环境变量(部分):');
console.log(' PATH:', process.env.PATH);
console.log(' HOME:', process.env.HOME);
console.log(' USER:', process.env.USER);
console.log(' LANG:', process.env.LANG);
}
printSystemInfo();
// 定时更新
setInterval(() => {
console.log('\n=== 更新时间:', new Date().toLocaleTimeString(), '===');
const memory = process.memoryUsage();
console.log('堆使用:', (memory.heapUsed / 1024 / 1024).toFixed(2), 'MB');
}, 5000);示例 2:日志记录器
// logger.js
const fs = require('fs');
const path = require('path');
class Logger {
constructor(options = {}) {
this.name = options.name || 'App';
this.level = options.level || 'info';
this.logFile = options.logFile || null;
this.levels = {
error: 0,
warn: 1,
info: 2,
debug: 3
};
}
formatMessage(level, message) {
const timestamp = new Date().toISOString();
return `[${timestamp}] [${this.name}] [${level.toUpperCase()}] ${message}`;
}
log(level, message) {
if (this.levels[level] > this.levels[this.level]) {
return;
}
const formattedMessage = this.formatMessage(level, message);
switch (level) {
case 'error':
console.error(formattedMessage);
break;
case 'warn':
console.warn(formattedMessage);
break;
case 'debug':
console.debug(formattedMessage);
break;
default:
console.log(formattedMessage);
}
if (this.logFile) {
this.writeToFile(formattedMessage);
}
}
writeToFile(message) {
try {
fs.appendFileSync(this.logFile, message + '\n', 'utf8');
} catch (error) {
console.error('写入日志文件失败:', error);
}
}
error(message) {
this.log('error', message);
}
warn(message) {
this.log('warn', message);
}
info(message) {
this.log('info', message);
}
debug(message) {
this.log('debug', message);
}
}
// 使用示例
const logger = new Logger({
name: 'MyApp',
level: 'debug',
logFile: path.join(__dirname, 'app.log')
});
logger.info('应用启动');
logger.debug('调试信息');
logger.warn('警告信息');
logger.error('错误信息');
// 模拟错误
try {
throw new Error('模拟错误');
} catch (error) {
logger.error(`发生错误:${error.message}`);
logger.debug(error.stack);
}示例 3:命令行参数解析器
// args-parser.js
function parseArgs(args) {
const parsed = {
_: [],
flags: {},
options: {}
};
for (let i = 0; i < args.length; i++) {
const arg = args[i];
if (arg.startsWith('--')) {
const key = arg.slice(2);
const nextArg = args[i + 1];
if (nextArg && !nextArg.startsWith('-')) {
parsed.options[key] = nextArg;
i++;
} else {
parsed.flags[key] = true;
}
} else if (arg.startsWith('-')) {
const key = arg.slice(1);
const nextArg = args[i + 1];
if (nextArg && !nextArg.startsWith('-')) {
parsed.options[key] = nextArg;
i++;
} else {
parsed.flags[key] = true;
}
} else {
parsed._.push(arg);
}
}
return parsed;
}
// 使用示例
const args = process.argv.slice(2);
const parsed = parseArgs(args);
console.log('解析结果:');
console.log('位置参数:', parsed._);
console.log('标志:', parsed.flags);
console.log('选项:', parsed.options);
// 示例命令:
// node args-parser.js input.txt output.txt --verbose --output=out.txt -f json实现技巧与注意事项
全局变量使用建议
- 避免污染全局命名空间:尽量减少全局变量的使用
- 使用模块代替全局变量:通过模块系统共享数据
- **谨慎使用 process.exit()**:确保资源正确释放后再退出
- 处理未捕获的异常:监听 uncaughtException 事件
console 输出优化
- 使用适当的日志级别:error、warn、info、debug
- 结构化日志:使用 JSON 格式便于解析
- 避免过度输出:减少不必要的日志
- 使用日志库:如 winston、bunyan 等
定时器使用注意事项
- 清除不需要的定时器:避免内存泄漏
- 注意定时器精度:setTimeout 不保证精确的时间
- 避免嵌套过深:使用递归 setTimeout 代替 setInterval
- 考虑使用 setImmediate:在 I/O 回调中优先使用
常见问题与解决方案
问题 1:process.exit() 导致资源未释放
// 问题代码
const fs = require('fs');
const stream = fs.createReadStream('large-file.txt');
stream.on('data', (chunk) => {
console.log('读取数据');
});
process.exit(0); // 可能导致文件未正确关闭
// 解决方案:确保资源正确释放
const fs = require('fs');
const stream = fs.createReadStream('large-file.txt');
stream.on('data', (chunk) => {
console.log('读取数据');
});
stream.on('end', () => {
console.log('读取完成');
process.exit(0);
});
stream.on('error', (error) => {
console.error('读取失败:', error);
process.exit(1);
});问题 2:定时器内存泄漏
// 问题代码
function createTimer() {
setInterval(() => {
console.log('定时任务');
}, 1000);
}
createTimer(); // 定时器没有被清除
// 解决方案:保存定时器 ID 并在需要时清除
const timers = [];
function createTimer() {
const timerId = setInterval(() => {
console.log('定时任务');
}, 1000);
timers.push(timerId);
return timerId;
}
const timerId = createTimer();
// 在需要时清除
setTimeout(() => {
clearInterval(timerId);
}, 5000);问题 3:console.log 性能问题
// 问题代码:大量日志输出
for (let i = 0; i < 100000; i++) {
console.log(i); // 性能很差
}
// 解决方案:减少日志输出或使用日志库
const winston = require('winston');
const logger = winston.createLogger({
level: 'info',
transports: [
new winston.transports.Console(),
new winston.transports.File({ filename: 'app.log' })
]
});
for (let i = 0; i < 100000; i++) {
if (i % 1000 === 0) {
logger.info(`处理进度:${i}`);
}
}问题 4:全局变量冲突
// 问题代码:全局变量可能被覆盖
global.myConfig = { name: 'App' };
// 其他模块可能覆盖
global.myConfig = { name: 'Other App' };
// 解决方案:使用模块系统
// config.js
module.exports = {
name: 'App'
};
// app.js
const config = require('./config');
console.log(config.name);总结
本教程详细介绍了 Node.js 的全局对象和全局变量,包括 global、process、console、定时器函数等重要内容。掌握这些全局对象对于编写高效的 Node.js 应用程序至关重要。
通过本集的学习,您应该能够:
- 理解 Node.js 全局对象的概念
- 使用 global 对象管理全局变量
- 使用 process 对象获取进程信息和控制进程
- 使用 console 对象进行日志输出和调试
- 使用定时器函数实现延迟和周期性任务
- 避免常见的全局对象使用错误
在下一集中,我们将学习 Node.js 的文件系统基础,这是 Node.js 编程的核心功能之一。继续加油,您的 Node.js 技能正在不断提升!