Node.js入门教程(二十四):常用工具(util 模块)

一、util 模块概述

util 模块是 Node.js 的一个内置模块,包含了实用工具函数,用于支持 JavaScript 编程中的调试、错误处理、格式化等功能。

util 提供常用函数的集合,用于弥补核心 JavaScript 的功能过于精简的不足。

util 模块中的功能涵盖了从对象检查、继承到格式化字符串等多个方面。

二、导入 util 模块

复制代码
const util = require('util');

三、常用方法概览

方法 描述
util.format(format, ...args) 字符串格式化,支持 %s%d%j 占位符
util.inspect(object[, options]) 将对象转换为字符串,用于调试
util.promisify(function) 将回调风格的函数转换为返回 Promise 的函数
util.callbackify(fn) 将返回 Promise 的函数转换为回调风格函数
util.inherits(constructor, superConstructor) 让一个构造函数继承另一个构造函数的原型方法
util.deprecate(fn, message) 标记函数为废弃,调用时会打印警告消息
util.types 包含多种类型检测方法的集合
util.isDeepStrictEqual(val1, val2) 判断两个值是否深度相等
util.getSystemErrorName(err) 根据错误码返回系统错误名称

四、常用方法详解

util.format() - 字符串格式化

util.format() 用于生成格式化字符串,支持占位符如 %s%d%j,分别代表字符串、数字和 JSON。

复制代码
const util = require('util');
const name = 'Alice';
const age = 25;

console.log(util.format('Name: %s, Age: %d', name, age));
// 输出: Name: Alice, Age: 25

console.log(util.format('JSON: %j', { key: 'value' }));
// 输出: JSON: {"key":"value"}

util.promisify() - 转换回调函数为 Promise

util.promisify() 将传统回调风格的函数转换为返回 Promise 的函数,从而可以与 async/await 一起使用。

复制代码
const util = require('util');
const fs = require('fs');

// 将回调风格的 fs.readFile 转换为返回 Promise 的函数
const readFileAsync = util.promisify(fs.readFile);

(async () => {
    try {
        const data = await readFileAsync('example.txt', 'utf8');
        console.log(data);
    } catch (err) {
        console.error(err);
    }
})();

util.callbackify() - 将 Promise 转换为回调

util.callbackify() 将返回 Promise 的函数转换为回调风格的函数,便于在需要回调的代码环境中使用。

util.callbackify(original)async 异步函数(或者一个返回值为 Promise 的函数)转换成遵循异常优先的回调风格 的函数,即将 (err, value) => ... 回调作为最后一个参数。在回调函数中,第一个参数为拒绝的原因(如果 Promise 解决,则为 null),第二个参数则是解决的值。

复制代码
const util = require('util');

async function fn() {
    return 'hello world';
}

const callbackFunction = util.callbackify(fn);

callbackFunction((err, ret) => {
    if (err) throw err;
    console.log(ret);
});

输出结果:

复制代码
hello world

注意 :回调函数是异步执行的,并且有异常堆栈错误追踪。如果回调函数抛出一个异常,进程会触发一个 'uncaughtException' 异常,如果没有被捕获,进程将会退出。

特殊处理 :如果回调函数的首个参数为 Promise 拒绝的原因且带有返回值,且值可以转换成布尔值 false,这个值会被封装在 Error 对象里,可以通过属性 reason 获取。

复制代码
function fn() {
    return Promise.reject(null);
}

const callbackFunction = util.callbackify(fn);

callbackFunction((err, ret) => {
    // 当 Promise 被以 null 拒绝时,它被包装为 Error 并且原始值存储在 reason 中
    err && err.hasOwnProperty('reason') && err.reason === null; // true
});

util.deprecate() - 标记函数为废弃

util.deprecate() 用于标记不推荐使用的函数,调用时会显示警告信息。

复制代码
const util = require('util');

const oldFunction = util.deprecate(() => {
    console.log('This function is deprecated');
}, 'oldFunction is deprecated. Use newFunction instead.');

oldFunction(); // 调用时会显示警告

util.inherits() - 实现继承

util.inherits(constructor, superConstructor) 是一个实现对象间原型继承的函数。

JavaScript 的面向对象特性是基于原型的,与常见的基于类的不同。JavaScript 没有提供对象继承的语言级别特性,而是通过原型复制来实现的。

复制代码
var util = require('util');

function Base() {
    this.name = 'base';
    this.base = 1991;
    this.sayHello = function() {
        console.log('Hello ' + this.name);
    };
}

Base.prototype.showName = function() {
    console.log(this.name);
};

function Sub() {
    this.name = 'sub';
}

util.inherits(Sub, Base);

var objBase = new Base();
objBase.showName(); // base
objBase.sayHello(); // Hello base
console.log(objBase);
// { name: 'base', base: 1991, sayHello: [Function] }

var objSub = new Sub();
objSub.showName(); // sub
console.log(objSub);
// { name: 'sub' }

运行结果:

复制代码
base
Hello base
{ name: 'base', base: 1991, sayHello: [Function] }
sub
{ name: 'sub' }

注意Sub 仅仅继承了 Base原型中定义的函数 (如 showName),而构造函数内部创建的 base 属性和 sayHello 函数都没有被 Sub 继承。

如果去掉 objSub.sayHello(); 这行的注释,将会看到错误:

复制代码
TypeError: Object #<Sub> has no method 'sayHello'

提示 :在 ES6 出现之前,util.inherits 是 Node.js 中实现继承的主要方法。但是,ES6 之后推荐使用 classextends 语法,这样继承的代码更具可读性。

util.inspect() - 打印对象结构

util.inspect(object[, options]) 将对象转换为字符串表示形式,便于调试。可以指定 options 参数来控制输出格式。

复制代码
const util = require('util');

const obj = { a: 1, b: 2, c: { d: 3 } };
console.log(util.inspect(obj, { showHidden: false, depth: null, colors: true }));

五、util.types 类型检测方法

util.types 是一个包含许多类型检测方法的集合,扩展了 JavaScript 的 typeofinstanceof

复制代码
const util = require('util');

console.log(util.types.isDate(new Date())); // true
console.log(util.types.isMap(new Map()));   // true
console.log(util.types.isSet(new Set()));   // true
console.log(util.types.isRegExp(/test/));   // true
console.log(util.types.isAsyncFunction(async () => {})); // true

常用类型检测方法

方法 描述
util.types.isAnyArrayBuffer(value) 检查是否为 ArrayBuffer 或 SharedArrayBuffer
util.types.isArrayBuffer(value) 检查是否为 ArrayBuffer
util.types.isAsyncFunction(value) 检查是否为异步函数
util.types.isBigInt64Array(value) 检查是否为 BigInt64Array
util.types.isBigUint64Array(value) 检查是否为 BigUint64Array
util.types.isBooleanObject(value) 检查是否为布尔对象
util.types.isDataView(value) 检查是否为 DataView
util.types.isDate(value) 检查是否为 Date
util.types.isGeneratorFunction(value) 检查是否为生成器函数
util.types.isMap(value) 检查是否为 Map
util.types.isSet(value) 检查是否为 Set
util.types.isRegExp(value) 检查是否为正则表达式
util.types.isSymbolObject(value) 检查是否为符号对象

六、旧版工具方法(已废弃)

以下方法在较新版本的 Node.js 中已废弃,了解即可。

util.isArray(object)

如果给定的参数 "object" 是一个数组返回 true,否则返回 false

复制代码
var util = require('util');

util.isArray([]);           // true
util.isArray(new Array());   // true
util.isArray({});            // false

util.isRegExp(object)

如果给定的参数 "object" 是一个正则表达式返回 true,否则返回 false

复制代码
util.isRegExp(/some regexp/);             // true
util.isRegExp(new RegExp('another regexp')); // true
util.isRegExp({});                        // false

util.isDate(object)

如果给定的参数 "object" 是一个日期返回 true,否则返回 false

复制代码
util.isDate(new Date()); // true
util.isDate(Date());     // false (without 'new' returns a String)
util.isDate({});         // false

七、本章小结

方法 用途
util.format() 格式化字符串
util.inspect() 将对象转为可读字符串,用于调试
util.promisify() 将回调函数转为 Promise(推荐
util.callbackify() 将 Promise 转为回调函数
util.inherits() 实现原型继承(ES6 后推荐用 class/extends
util.deprecate() 标记废弃函数
util.types 增强的类型检测工具集

提示util.promisify 是日常开发中最常用的方法,它让你能够将大量基于回调的 Node.js 核心模块函数转换为返回 Promise 的函数,从而与 async/await 完美配合。在新代码中,推荐使用 classextends 语法替代 util.inherits

相关推荐
FungLeo6 小时前
成为全栈·Node 后端篇·配置管理:环境变量、多环境与密钥安全
node.js·环境变量·多环境配置·密钥安全
FungLeo7 小时前
成为全栈·Node 后端篇·错误处理:异常分层与全局捕获
node.js·错误处理·异常分层·全局捕获·成为全栈
百万运营Pro14 小时前
用 Astro + Supabase 从零构建全网盘聚合搜索引擎:PGroonga 中文检索实战
搜索引擎·前端框架·node.js·个人开发·学习方法·ai编程·资源分享
小婉1 天前
我用 Next.js + React Flow 从零搭建了一个可视化 AI 工作流编排平台
前端·人工智能·node.js
抓不住时间的沙1 天前
N1搭建守护环境以及重装 Armbian 后完整恢复整套守护环境,清理日志步骤
node.js
meilindehuzi_a1 天前
从域名到数据库:React + Node.js 项目部署全流程与用户访问链路
数据库·react.js·node.js
李游Leo2 天前
Node.js 开发环境安装与 npm/pnpm 国内镜像配置(Windows / macOS / Linux)
npm·node.js·pnpm·前端开发·开发环境
阿黎梨梨3 天前
AI也有记忆?LangChain Memory 管理指南
langchain·node.js·llm
小小龙学IT3 天前
libuv 开源异步 I/O 事件循环库深度解析:Node.js 的心脏,C++ 高性能网络程序的引擎
c++·开源·node.js
用户672465366054 天前
Node 守护进程日志转发踩坑记:stdio 管道、UTF-8 截断,和一个字符串按值传参的故事
node.js