Node.js util 模块
继承、类型判断、调试输出、以及 promisify 之外的那些工具。
Key Points`util.inherits` 是 ES5 时代的遗产,新代码用 `class extends`。
继承
JavaScript
const util = require('node:util');
const { EventEmitter } = require('node:events');
// 老写法(ES5)
function Old() {
EventEmitter.call(this);
}
util.inherits(Old, EventEmitter);
// 新写法(ES6+,推荐)
class New extends EventEmitter {}
const n = new New();
n.on('x', (v) => console.log('收到', v));
n.emit('x', 1);Output
收到 1类型判断
JavaScript
const { types } = require('node:util');
const checks = [
['isPromise', Promise.resolve()],
['isDate', new Date()],
['isRegExp', /x/],
['isMap', new Map()],
['isTypedArray', new Uint8Array(4)],
['isProxy', new Proxy({}, {})],
];
for (const [fn, val] of checks) {
console.log(fn, types[fn](val));
}Output
isPromise true
isDate true
isRegExp true
isMap true
isTypedArray true
isProxy trueutil.types reads V8 internal type tags, so it beats instanceof and typeof — especially across vm contexts and worker_threads.
调试输出
JavaScript
const util = require('node:util');
const debug = util.debuglog('db');
debug('连接 %s', 'mysql://localhost'); // 默认不输出Bash
NODE_DEBUG=db node app.jsOutput
DB 24188: 连接 mysql://localhostdebuglog is a zero-dependency conditional logger: silent by default, enabled by an env var. Cleaner than sprinkling if (DEBUG).
废弃警告
JavaScript
const util = require('node:util');
const oldApi = util.deprecate(
(x) => x * 2,
'oldApi 将在 v3 移除,请改用 newApi',
'DEP0001'
);
oldApi(2); // 正常返回值,但打印一条 DeprecationWarningOutput
(node:24188) DeprecationWarning: oldApi 将在 v3 移除,请改用 newApi
(Use `node --trace-deprecation ...` to show where the warning was created)其他常用
| API | Use |
|---|---|
util.format | printf 风格格式化 |
util.inspect | 把对象转成可读字符串 |
util.isDeepStrictEqual | 严格深比较 |
util.parseArgs | 解析命令行参数 |
util.aborted | 把 signal 转成 Promise |
util.stripVTControlCharacters | 去掉终端颜色码 |
JavaScript
const util = require('node:util');
const ac = new AbortController();
setTimeout(() => ac.abort(), 100);
await util.aborted(ac.signal);
console.log('已中止');Output
已中止继承
JavaScript
const util = require('node:util');
const { EventEmitter } = require('node:events');
// 老写法(ES5)
function Old() {
EventEmitter.call(this);
}
util.inherits(Old, EventEmitter);
// 新写法(ES6+,推荐)
class New extends EventEmitter {}
const n = new New();
n.on('x', (v) => console.log('收到', v));
n.emit('x', 1);Output
收到 1类型判断
JavaScript
const { types } = require('node:util');
const checks = [
['isPromise', Promise.resolve()],
['isDate', new Date()],
['isRegExp', /x/],
['isMap', new Map()],
['isTypedArray', new Uint8Array(4)],
['isProxy', new Proxy({}, {})],
];
for (const [fn, val] of checks) {
console.log(fn, types[fn](val));
}Output
isPromise true
isDate true
isRegExp true
isMap true
isTypedArray true
isProxy trueutil.types 用的是 V8 内部类型标记,比 instanceof 和 typeof 都准,尤其在跨 vm 上下文和 worker_threads 时。
调试输出
JavaScript
const util = require('node:util');
const debug = util.debuglog('db');
debug('连接 %s', 'mysql://localhost'); // 默认不输出Bash
NODE_DEBUG=db node app.jsOutput
DB 24188: 连接 mysql://localhostdebuglog 是零依赖的条件日志:平时完全静默,需要时用环境变量打开。比到处 if (DEBUG) 干净。
废弃警告
JavaScript
const util = require('node:util');
const oldApi = util.deprecate(
(x) => x * 2,
'oldApi 将在 v3 移除,请改用 newApi',
'DEP0001'
);
oldApi(2); // 正常返回值,但打印一条 DeprecationWarningOutput
(node:24188) DeprecationWarning: oldApi 将在 v3 移除,请改用 newApi
(Use `node --trace-deprecation ...` to show where the warning was created)其他常用
| API | 用途 |
|---|---|
util.format | printf 风格格式化 |
util.inspect | 把对象转成可读字符串 |
util.isDeepStrictEqual | 严格深比较 |
util.parseArgs | 解析命令行参数 |
util.aborted | 把 signal 转成 Promise |
util.stripVTControlCharacters | 去掉终端颜色码 |
JavaScript
const util = require('node:util');
const ac = new AbortController();
setTimeout(() => ac.abort(), 100);
await util.aborted(ac.signal);
console.log('已中止');Output
已中止