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

相关推荐
oushaojun22 小时前
使用docker安装node.js和deepseek harness
node.js·dsh
爱丶不疚2 小时前
搞不清 CommonJS 与 ESM,你是否也有这些疑问🤔
前端·node.js
cyadyx5 小时前
Vite 比 Webpack 构建效率更高
前端·webpack·node.js·vite
烂蜻蜓21 小时前
Node.js入门教程(十一):异步编程
node.js
Sca_杰1 天前
微信客服API对接速通
javascript·node.js
FungLeo1 天前
Node 后端实战 · D1 那些坑:100 参数上限逼出的批量写入重构
node.js·serverless·d1 数据库·sqli
谦卑a1 天前
nodejs安装保姆级教程
前端·javascript·node.js·个人开发
烂蜻蜓1 天前
Node.js入门教程(十八):Stream(流)
node.js
东方小月2 天前
从零开发一个 Coding Agent(九):实现 Agent 的工具调用闭环
人工智能·前端框架·node.js