Util#

稳定性:2 - 稳定

源代码: lib/util.js

`node:util` 模块支持 Node.js 内部 API 的需求。许多实用工具对应用程序和模块开发者也很有用。要访问它:

import util from 'node:util';const util = require('node:util');

util.callbackify(original)#

接受一个 `async` 函数(或返回 `Promise` 的函数),并返回一个遵循错误优先回调风格的函数,即接受一个 `(err, value) => ...` 回调作为最后一个参数。在回调中,第一个参数将是拒绝原因(如果 `Promise` 解析成功,则为 `null`),第二个参数将是解析后的值。

import { callbackify } from 'node:util';

async function fn() {
  return 'hello world';
}
const callbackFunction = callbackify(fn);

callbackFunction((err, ret) => {
  if (err) throw err;
  console.log(ret);
});const { callbackify } = require('node:util');

async function fn() {
  return 'hello world';
}
const callbackFunction = callbackify(fn);

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

将打印出:

hello world 

回调是异步执行的,并且会有一个有限的堆栈跟踪。如果回调函数抛出异常,进程将触发一个 `'uncaughtException'` 事件,如果未处理,将会退出。

由于 `null` 作为回调的第一个参数有特殊含义,如果一个被包装的函数以一个假值(falsy value)作为原因拒绝了一个 `Promise`,这个值将被包装在一个 `Error` 对象中,原始值存储在一个名为 `reason` 的字段里。

function fn() {
  return Promise.reject(null);
}
const callbackFunction = util.callbackify(fn);

callbackFunction((err, ret) => {
  // When the Promise was rejected with `null` it is wrapped with an Error and
  // the original value is stored in `reason`.
  err && Object.hasOwn(err, 'reason') && err.reason === null;  // true
}); 

util.debuglog(section[, callback])#

  • section <string> 一个标识应用程序部分的字符串,为其创建 `debuglog` 函数。
  • callback <Function> 一个回调函数,在日志函数第一次被调用时以一个更优化的日志函数作为参数来调用。
  • 返回:<Function> 日志函数

`util.debuglog()` 方法用于创建一个函数,该函数根据 `NODE_DEBUG` 环境变量的存在与否,有条件地向 `stderr` 写入调试信息。如果 `section` 名称出现在该环境变量的值中,那么返回的函数操作类似于 `console.error()`。否则,返回的函数是一个空操作(no-op)。

import { debuglog } from 'node:util';
const log = debuglog('foo');

log('hello from foo [%d]', 123);const { debuglog } = require('node:util');
const log = debuglog('foo');

log('hello from foo [%d]', 123);

如果在环境中设置 `NODE_DEBUG=foo` 来运行此程序,它将输出类似以下内容:

FOO 3245: hello from foo [123] 

其中 `3245` 是进程 ID。如果没有设置该环境变量就运行,它将不会打印任何内容。

`section` 也支持通配符:

import { debuglog } from 'node:util';
const log = debuglog('foo');

log('hi there, it\'s foo-bar [%d]', 2333);const { debuglog } = require('node:util');
const log = debuglog('foo');

log('hi there, it\'s foo-bar [%d]', 2333);

如果在环境中设置 `NODE_DEBUG=foo*` 来运行,它将输出类似以下内容:

FOO-BAR 3257: hi there, it's foo-bar [2333] 

可以在 `NODE_DEBUG` 环境变量中指定多个以逗号分隔的 `section` 名称:`NODE_DEBUG=fs,net,tls`。

可选的 `callback` 参数可用于将日志函数替换为另一个没有任何初始化或不必要包装的函数。

import { debuglog } from 'node:util';
let log = debuglog('internals', (debug) => {
  // Replace with a logging function that optimizes out
  // testing if the section is enabled
  log = debug;
});const { debuglog } = require('node:util');
let log = debuglog('internals', (debug) => {
  // Replace with a logging function that optimizes out
  // testing if the section is enabled
  log = debug;
});

debuglog().enabled#

`util.debuglog().enabled` getter 用于创建一个可以在条件语句中使用的测试,该测试基于 `NODE_DEBUG` 环境变量的存在。如果 `section` 名称出现在该环境变量的值中,则返回值为 `true`。否则,返回值为 `false`。

import { debuglog } from 'node:util';
const enabled = debuglog('foo').enabled;
if (enabled) {
  console.log('hello from foo [%d]', 123);
}const { debuglog } = require('node:util');
const enabled = debuglog('foo').enabled;
if (enabled) {
  console.log('hello from foo [%d]', 123);
}

如果在环境中设置 `NODE_DEBUG=foo` 来运行此程序,它将输出类似以下内容:

hello from foo [123] 

util.debug(section)#

`util.debuglog` 的别名。当仅使用 `util.debuglog().enabled` 时,这种用法可以提高可读性,不暗示日志记录。

util.deprecate(fn, msg[, code])#

`util.deprecate()` 方法将 `fn`(可以是一个函数或类)包装起来,使其被标记为已废弃。

import { deprecate } from 'node:util';

export const obsoleteFunction = deprecate(() => {
  // Do something here.
}, 'obsoleteFunction() is deprecated. Use newShinyFunction() instead.');const { deprecate } = require('node:util');

exports.obsoleteFunction = deprecate(() => {
  // Do something here.
}, 'obsoleteFunction() is deprecated. Use newShinyFunction() instead.');

当被调用时,`util.deprecate()` 将返回一个函数,该函数会使用 `'warning'` 事件发出一个 `DeprecationWarning`。在返回的函数第一次被调用时,警告会被发出并打印到 `stderr`。警告发出后,包装的函数会被调用,但不会再发出警告。

如果在多次调用 `util.deprecate()` 时提供了相同的可选 `code`,则该 `code` 的警告只会发出一次。

import { deprecate } from 'node:util';

const fn1 = deprecate(
  () => 'a value',
  'deprecation message',
  'DEP0001',
);
const fn2 = deprecate(
  () => 'a  different value',
  'other dep message',
  'DEP0001',
);
fn1(); // Emits a deprecation warning with code DEP0001
fn2(); // Does not emit a deprecation warning because it has the same codeconst { deprecate } = require('node:util');

const fn1 = deprecate(
  function() {
    return 'a value';
  },
  'deprecation message',
  'DEP0001',
);
const fn2 = deprecate(
  function() {
    return 'a  different value';
  },
  'other dep message',
  'DEP0001',
);
fn1(); // Emits a deprecation warning with code DEP0001
fn2(); // Does not emit a deprecation warning because it has the same code

如果使用了 `--no-deprecation` 或 `--no-warnings` 命令行标志,或者在第一次废弃警告之前将 `process.noDeprecation` 属性设置为 `true`,那么 `util.deprecate()` 方法将什么也不做。

如果设置了 `--trace-deprecation` 或 `--trace-warnings` 命令行标志,或者 `process.traceDeprecation` 属性被设置为 `true`,那么在第一次调用被废弃的函数时,会向 `stderr` 打印警告和堆栈跟踪。

如果设置了 `--throw-deprecation` 命令行标志,或者 `process.throwDeprecation` 属性被设置为 `true`,那么在调用被废弃的函数时会抛出异常。

`--throw-deprecation` 命令行标志和 `process.throwDeprecation` 属性的优先级高于 `--trace-deprecation` 和 `process.traceDeprecation`。

util.diff(actual, expected)#

稳定性:1 - 实验性

  • actual <Array> | <string> 要比较的第一个值

  • expected <Array> | <string> 要比较的第二个值

  • 返回:<Array> 一个差异条目的数组。每个条目是一个包含两个元素的数组:

    • 0 <number> 操作码:`-1` 代表删除,`0` 代表无操作/未更改,`1` 代表插入
    • 1 <string> 与操作关联的值
  • 算法复杂度:O(N*D),其中

  • N 是两个序列的总长度之和 (N = actual.length + expected.length)

  • D 是编辑距离(将一个序列转换为另一个序列所需的最少操作数)。

`util.diff()` 比较两个字符串或数组值,并返回一个差异条目数组。它使用 Myers 差异算法来计算最小差异,这与断言错误消息内部使用的算法相同。

如果值相等,则返回一个空数组。

const { diff } = require('node:util');

// Comparing strings
const actualString = '12345678';
const expectedString = '12!!5!7!';
console.log(diff(actualString, expectedString));
// [
//   [0, '1'],
//   [0, '2'],
//   [1, '3'],
//   [1, '4'],
//   [-1, '!'],
//   [-1, '!'],
//   [0, '5'],
//   [1, '6'],
//   [-1, '!'],
//   [0, '7'],
//   [1, '8'],
//   [-1, '!'],
// ]
// Comparing arrays
const actualArray = ['1', '2', '3'];
const expectedArray = ['1', '3', '4'];
console.log(diff(actualArray, expectedArray));
// [
//   [0, '1'],
//   [1, '2'],
//   [0, '3'],
//   [-1, '4'],
// ]
// Equal values return empty array
console.log(diff('same', 'same'));
// [] 

util.format(format[, ...args])#

  • format <string> 一个类似 `printf` 的格式字符串。

`util.format()` 方法返回一个格式化的字符串,使用第一个参数作为类似 `printf` 的格式字符串,其中可以包含零个或多个格式说明符。每个说明符都会被相应参数转换后的值所替换。支持的说明符有:

  • %s: `String` 将用于转换除 `BigInt`、`Object` 和 `-0` 之外的所有值。`BigInt` 值将用 `n` 表示,而没有用户定义的 `toString` 函数或 `Symbol.toPrimitive` 函数的 `Object` 将使用 `util.inspect()` 进行检查,选项为 `{ depth: 0, colors: false, compact: 3 }`。
  • %d: `Number` 将用于转换除 `BigInt` 和 `Symbol` 之外的所有值。
  • %i: `parseInt(value, 10)` 用于除 `BigInt` 和 `Symbol` 之外的所有值。
  • %f: `parseFloat(value)` 用于除 `Symbol` 之外的所有值。
  • %j: JSON。如果参数包含循环引用,则替换为字符串 `'[Circular]'`。
  • %o: `Object`。对象的字符串表示,使用通用的 JavaScript 对象格式。类似于 `util.inspect()` 并带有选项 `{ showHidden: true, showProxy: true }`。这将显示完整的对象,包括不可枚举的属性和代理。
  • %O: `Object`。对象的字符串表示,使用通用的 JavaScript 对象格式。类似于不带选项的 `util.inspect()`。这将显示完整的对象,但不包括不可枚举的属性和代理。
  • %c: `CSS`。此说明符被忽略,并将跳过任何传入的 CSS。
  • %%: 单个百分号 (`'%'`)。这不消耗参数。
  • 返回:<string> 格式化后的字符串

如果一个说明符没有对应的参数,它将不会被替换:

util.format('%s:%s', 'foo');
// Returns: 'foo:%s' 

不属于格式字符串一部分的值,如果其类型不是 `string`,则使用 `util.inspect()` 进行格式化。

如果传递给 `util.format()` 方法的参数多于说明符的数量,多余的参数将被连接到返回的字符串后面,并用空格分隔:

util.format('%s:%s', 'foo', 'bar', 'baz');
// Returns: 'foo:bar baz' 

如果第一个参数不包含有效的格式说明符,`util.format()` 会返回一个由所有参数以空格分隔连接而成的字符串:

util.format(1, 2, 3);
// Returns: '1 2 3' 

如果只向 `util.format()` 传递一个参数,它将按原样返回,不进行任何格式化:

util.format('%% %s');
// Returns: '%% %s' 

`util.format()` 是一个同步方法,旨在作为调试工具。某些输入值可能会产生显著的性能开销,从而阻塞事件循环。请谨慎使用此函数,切勿在热代码路径中使用。

util.formatWithOptions(inspectOptions, format[, ...args])#

此函数与 `util.format()` 完全相同,区别在于它接受一个 `inspectOptions` 参数,该参数指定了传递给 `util.inspect()` 的选项。

util.formatWithOptions({ colors: true }, 'See object %O', { foo: 42 });
// Returns 'See object { foo: 42 }', where `42` is colored as a number
// when printed to a terminal. 

util.getCallSites([frameCount][, options])#

稳定性:1.1 - 活跃开发

  • frameCount <number> 可选的捕获为调用点对象的帧数。默认值: `10`。允许范围在 1 到 200 之间。
  • options <Object> 可选
    • sourceMap <boolean> 从源映射(source-map)重建堆栈跟踪中的原始位置。使用 `--enable-source-maps` 标志时默认启用。
  • 返回:<Object[]> 一个调用点对象的数组
    • functionName <string> 返回与此调用点关联的函数名称。
    • scriptName <string> 返回包含此调用点函数脚本的资源名称。
    • scriptId <string> 返回脚本的唯一 ID,与 Chrome DevTools 协议中的 `Runtime.ScriptId` 相同。
    • lineNumber <number> 返回 JavaScript 脚本的行号(从 1 开始)。
    • columnNumber <number> 返回 JavaScript 脚本的列号(从 1 开始)。

返回一个包含调用者函数堆栈的调用点对象数组。

import { getCallSites } from 'node:util';

function exampleFunction() {
  const callSites = getCallSites();

  console.log('Call Sites:');
  callSites.forEach((callSite, index) => {
    console.log(`CallSite ${index + 1}:`);
    console.log(`Function Name: ${callSite.functionName}`);
    console.log(`Script Name: ${callSite.scriptName}`);
    console.log(`Line Number: ${callSite.lineNumber}`);
    console.log(`Column Number: ${callSite.column}`);
  });
  // CallSite 1:
  // Function Name: exampleFunction
  // Script Name: /home/example.js
  // Line Number: 5
  // Column Number: 26

  // CallSite 2:
  // Function Name: anotherFunction
  // Script Name: /home/example.js
  // Line Number: 22
  // Column Number: 3

  // ...
}

// A function to simulate another stack layer
function anotherFunction() {
  exampleFunction();
}

anotherFunction();const { getCallSites } = require('node:util');

function exampleFunction() {
  const callSites = getCallSites();

  console.log('Call Sites:');
  callSites.forEach((callSite, index) => {
    console.log(`CallSite ${index + 1}:`);
    console.log(`Function Name: ${callSite.functionName}`);
    console.log(`Script Name: ${callSite.scriptName}`);
    console.log(`Line Number: ${callSite.lineNumber}`);
    console.log(`Column Number: ${callSite.column}`);
  });
  // CallSite 1:
  // Function Name: exampleFunction
  // Script Name: /home/example.js
  // Line Number: 5
  // Column Number: 26

  // CallSite 2:
  // Function Name: anotherFunction
  // Script Name: /home/example.js
  // Line Number: 22
  // Column Number: 3

  // ...
}

// A function to simulate another stack layer
function anotherFunction() {
  exampleFunction();
}

anotherFunction();

通过将 `sourceMap` 选项设置为 `true`,可以重建原始位置。如果源映射不可用,原始位置将与当前位置相同。当启用 `--enable-source-maps` 标志时(例如,使用 `--experimental-transform-types` 时),`sourceMap` 默认将为 `true`。

import { getCallSites } from 'node:util';

interface Foo {
  foo: string;
}

const callSites = getCallSites({ sourceMap: true });

// With sourceMap:
// Function Name: ''
// Script Name: example.js
// Line Number: 7
// Column Number: 26

// Without sourceMap:
// Function Name: ''
// Script Name: example.js
// Line Number: 2
// Column Number: 26 
const { getCallSites } = require('node:util');

const callSites = getCallSites({ sourceMap: true });

// With sourceMap:
// Function Name: ''
// Script Name: example.js
// Line Number: 7
// Column Number: 26

// Without sourceMap:
// Function Name: ''
// Script Name: example.js
// Line Number: 2
// Column Number: 26 

util.getSystemErrorName(err)#

返回来自 Node.js API 的数字错误码的字符串名称。错误码和错误名称之间的映射是平台相关的。常见错误的名称请参见常见系统错误

fs.access('file/that/does/not/exist', (err) => {
  const name = util.getSystemErrorName(err.errno);
  console.error(name);  // ENOENT
}); 

util.getSystemErrorMap()#

返回 Node.js API 中所有可用的系统错误码的 Map。错误码和错误名称之间的映射是平台相关的。常见错误的名称请参见常见系统错误

fs.access('file/that/does/not/exist', (err) => {
  const errorMap = util.getSystemErrorMap();
  const name = errorMap.get(err.errno);
  console.error(name);  // ENOENT
}); 

util.getSystemErrorMessage(err)#

返回来自 Node.js API 的数字错误码的字符串消息。错误码和字符串消息之间的映射是平台相关的。

fs.access('file/that/does/not/exist', (err) => {
  const message = util.getSystemErrorMessage(err.errno);
  console.error(message);  // No such file or directory
}); 

util.setTraceSigInt(enable)#

启用或禁用在 `SIGINT` 上打印堆栈跟踪。此 API 仅在主线程上可用。

util.inherits(constructor, superConstructor)#

稳定性:3 - 旧版:请改用 ES2015 class 语法和 `extends` 关键字。

不鼓励使用 `util.inherits()`。请使用 ES6 的 `class` 和 `extends` 关键字来获得语言层面的继承支持。另请注意,这两种风格在语义上不兼容

将一个构造函数的原型方法继承到另一个构造函数。`constructor` 的原型将被设置为一个从 `superConstructor` 创建的新对象。

这主要是在 `Object.setPrototypeOf(constructor.prototype, superConstructor.prototype)` 的基础上增加了一些输入验证。作为一个额外的便利,`superConstructor` 将可以通过 `constructor.super_` 属性访问。

const util = require('node:util');
const EventEmitter = require('node:events');

function MyStream() {
  EventEmitter.call(this);
}

util.inherits(MyStream, EventEmitter);

MyStream.prototype.write = function(data) {
  this.emit('data', data);
};

const stream = new MyStream();

console.log(stream instanceof EventEmitter); // true
console.log(MyStream.super_ === EventEmitter); // true

stream.on('data', (data) => {
  console.log(`Received data: "${data}"`);
});
stream.write('It works!'); // Received data: "It works!" 

使用 `class` 和 `extends` 的 ES6 示例:

import EventEmitter from 'node:events';

class MyStream extends EventEmitter {
  write(data) {
    this.emit('data', data);
  }
}

const stream = new MyStream();

stream.on('data', (data) => {
  console.log(`Received data: "${data}"`);
});
stream.write('With ES6');const EventEmitter = require('node:events');

class MyStream extends EventEmitter {
  write(data) {
    this.emit('data', data);
  }
}

const stream = new MyStream();

stream.on('data', (data) => {
  console.log(`Received data: "${data}"`);
});
stream.write('With ES6');

util.inspect(object[, options])#

util.inspect(object[, showHidden[, depth[, colors]]])#

  • object <any> 任何 JavaScript 原始类型或 `Object`。
  • options <Object>
    • showHidden <boolean> 如果为 `true`,`object` 的不可枚举符号和属性将包含在格式化结果中。<WeakMap><WeakSet> 的条目以及用户定义的原型属性(不包括方法属性)也会被包含。默认值: `false`。
    • depth <number> 指定在格式化 `object` 时递归的次数。这对于检查大型对象很有用。要递归到最大调用堆栈大小,请传入 `Infinity` 或 `null`。默认值: `2`。
    • colors <boolean> 如果为 `true`,输出将使用 ANSI 颜色代码进行样式化。颜色是可自定义的。请参阅自定义 `util.inspect` 颜色默认值: `false`。
    • customInspect <boolean> 如果为 `false`,则不调用 `[util.inspect.custom](depth, opts, inspect)` 函数。默认值: `true`。
    • showProxy <boolean> 如果为 `true`,`Proxy` 检查将包括`target` 和 `handler` 对象。默认值: `false`。
    • maxArrayLength <integer> 指定在格式化时要包含的 `Array`、<TypedArray><Map><WeakMap><WeakSet> 元素的最大数量。设置为 `null` 或 `Infinity` 以显示所有元素。设置为 `0` 或负数则不显示任何元素。默认值: `100`。
    • maxStringLength <integer> 指定格式化时要包含的最大字符数。设置为 `null` 或 `Infinity` 以显示所有字符。设置为 `0` 或负数则不显示任何字符。默认值: `10000`。
    • breakLength <integer> 输入值在多行显示时的长度阈值。设置为 `Infinity` 可将输入格式化为单行(与 `compact` 设置为 `true` 或任何 >= `1` 的数字结合使用)。默认值: `80`。
    • compact <boolean> | <integer> 将此设置为 `false` 会导致每个对象键都显示在新行上。它会在长于 `breakLength` 的文本中换行。如果设置为一个数字 `n`,只要所有属性都适合 `breakLength`,最内层的 `n` 个元素就会合并到一行。短数组元素也会被组合在一起。更多信息请参见下面的示例。默认值: `3`。
    • sorted <boolean> | <Function> 如果设置为 `true` 或一个函数,则对象的所有属性以及 `Set` 和 `Map` 的条目将在结果字符串中排序。如果设置为 `true`,则使用默认排序。如果设置为一个函数,它将被用作比较函数
    • getters <boolean> | <string> 如果设置为 `true`,则检查 getters。如果设置为 `'get'`,只检查没有对应 setter 的 getters。如果设置为 `'set'`,只检查有对应 setter 的 getters。这可能会根据 getter 函数的不同而产生副作用。默认值: `false`。
    • numericSeparator <boolean> 如果设置为 `true`,则在所有 bigint 和 number 中每三位数字使用一个下划线分隔。默认值: `false`。
  • 返回:<string> `object` 的表示。

`util.inspect()` 方法返回一个用于调试的 `object` 的字符串表示。`util.inspect` 的输出可能随时更改,不应在程序中依赖它。可以传递额外的 `options` 来改变结果。`util.inspect()` 将使用构造函数的名称和/或 `Symbol.toStringTag` 属性来为被检查的值创建一个可识别的标签。

class Foo {
  get [Symbol.toStringTag]() {
    return 'bar';
  }
}

class Bar {}

const baz = Object.create(null, { [Symbol.toStringTag]: { value: 'foo' } });

util.inspect(new Foo()); // 'Foo [bar] {}'
util.inspect(new Bar()); // 'Bar {}'
util.inspect(baz);       // '[foo] {}' 

循环引用通过使用引用索引指向其锚点:

import { inspect } from 'node:util';

const obj = {};
obj.a = [obj];
obj.b = {};
obj.b.inner = obj.b;
obj.b.obj = obj;

console.log(inspect(obj));
// <ref *1> {
//   a: [ [Circular *1] ],
//   b: <ref *2> { inner: [Circular *2], obj: [Circular *1] }
// }const { inspect } = require('node:util');

const obj = {};
obj.a = [obj];
obj.b = {};
obj.b.inner = obj.b;
obj.b.obj = obj;

console.log(inspect(obj));
// <ref *1> {
//   a: [ [Circular *1] ],
//   b: <ref *2> { inner: [Circular *2], obj: [Circular *1] }
// }

以下示例检查 `util` 对象的所有属性:

import util from 'node:util';

console.log(util.inspect(util, { showHidden: true, depth: null }));const util = require('node:util');

console.log(util.inspect(util, { showHidden: true, depth: null }));

以下示例突出了 `compact` 选项的效果:

import { inspect } from 'node:util';

const o = {
  a: [1, 2, [[
    'Lorem ipsum dolor sit amet,\nconsectetur adipiscing elit, sed do ' +
      'eiusmod \ntempor incididunt ut labore et dolore magna aliqua.',
    'test',
    'foo']], 4],
  b: new Map([['za', 1], ['zb', 'test']]),
};
console.log(inspect(o, { compact: true, depth: 5, breakLength: 80 }));

// { a:
//   [ 1,
//     2,
//     [ [ 'Lorem ipsum dolor sit amet,\nconsectetur [...]', // A long line
//           'test',
//           'foo' ] ],
//     4 ],
//   b: Map(2) { 'za' => 1, 'zb' => 'test' } }

// Setting `compact` to false or an integer creates more reader friendly output.
console.log(inspect(o, { compact: false, depth: 5, breakLength: 80 }));

// {
//   a: [
//     1,
//     2,
//     [
//       [
//         'Lorem ipsum dolor sit amet,\n' +
//           'consectetur adipiscing elit, sed do eiusmod \n' +
//           'tempor incididunt ut labore et dolore magna aliqua.',
//         'test',
//         'foo'
//       ]
//     ],
//     4
//   ],
//   b: Map(2) {
//     'za' => 1,
//     'zb' => 'test'
//   }
// }

// Setting `breakLength` to e.g. 150 will print the "Lorem ipsum" text in a
// single line.const { inspect } = require('node:util');

const o = {
  a: [1, 2, [[
    'Lorem ipsum dolor sit amet,\nconsectetur adipiscing elit, sed do ' +
      'eiusmod \ntempor incididunt ut labore et dolore magna aliqua.',
    'test',
    'foo']], 4],
  b: new Map([['za', 1], ['zb', 'test']]),
};
console.log(inspect(o, { compact: true, depth: 5, breakLength: 80 }));

// { a:
//   [ 1,
//     2,
//     [ [ 'Lorem ipsum dolor sit amet,\nconsectetur [...]', // A long line
//           'test',
//           'foo' ] ],
//     4 ],
//   b: Map(2) { 'za' => 1, 'zb' => 'test' } }

// Setting `compact` to false or an integer creates more reader friendly output.
console.log(inspect(o, { compact: false, depth: 5, breakLength: 80 }));

// {
//   a: [
//     1,
//     2,
//     [
//       [
//         'Lorem ipsum dolor sit amet,\n' +
//           'consectetur adipiscing elit, sed do eiusmod \n' +
//           'tempor incididunt ut labore et dolore magna aliqua.',
//         'test',
//         'foo'
//       ]
//     ],
//     4
//   ],
//   b: Map(2) {
//     'za' => 1,
//     'zb' => 'test'
//   }
// }

// Setting `breakLength` to e.g. 150 will print the "Lorem ipsum" text in a
// single line.

`showHidden` 选项允许检查 <WeakMap><WeakSet> 的条目。如果条目数多于 `maxArrayLength`,则无法保证显示哪些条目。这意味着两次检索同一个 <WeakSet> 的条目可能会得到不同的输出。此外,没有剩余强引用的条目可能随时被垃圾回收。

import { inspect } from 'node:util';

const obj = { a: 1 };
const obj2 = { b: 2 };
const weakSet = new WeakSet([obj, obj2]);

console.log(inspect(weakSet, { showHidden: true }));
// WeakSet { { a: 1 }, { b: 2 } }const { inspect } = require('node:util');

const obj = { a: 1 };
const obj2 = { b: 2 };
const weakSet = new WeakSet([obj, obj2]);

console.log(inspect(weakSet, { showHidden: true }));
// WeakSet { { a: 1 }, { b: 2 } }

`sorted` 选项确保对象的属性插入顺序不影响 `util.inspect()` 的结果。

import { inspect } from 'node:util';
import assert from 'node:assert';

const o1 = {
  b: [2, 3, 1],
  a: '`a` comes before `b`',
  c: new Set([2, 3, 1]),
};
console.log(inspect(o1, { sorted: true }));
// { a: '`a` comes before `b`', b: [ 2, 3, 1 ], c: Set(3) { 1, 2, 3 } }
console.log(inspect(o1, { sorted: (a, b) => b.localeCompare(a) }));
// { c: Set(3) { 3, 2, 1 }, b: [ 2, 3, 1 ], a: '`a` comes before `b`' }

const o2 = {
  c: new Set([2, 1, 3]),
  a: '`a` comes before `b`',
  b: [2, 3, 1],
};
assert.strict.equal(
  inspect(o1, { sorted: true }),
  inspect(o2, { sorted: true }),
);const { inspect } = require('node:util');
const assert = require('node:assert');

const o1 = {
  b: [2, 3, 1],
  a: '`a` comes before `b`',
  c: new Set([2, 3, 1]),
};
console.log(inspect(o1, { sorted: true }));
// { a: '`a` comes before `b`', b: [ 2, 3, 1 ], c: Set(3) { 1, 2, 3 } }
console.log(inspect(o1, { sorted: (a, b) => b.localeCompare(a) }));
// { c: Set(3) { 3, 2, 1 }, b: [ 2, 3, 1 ], a: '`a` comes before `b`' }

const o2 = {
  c: new Set([2, 1, 3]),
  a: '`a` comes before `b`',
  b: [2, 3, 1],
};
assert.strict.equal(
  inspect(o1, { sorted: true }),
  inspect(o2, { sorted: true }),
);

`numericSeparator` 选项为所有数字每三位添加一个下划线。

import { inspect } from 'node:util';

const thousand = 1000;
const million = 1000000;
const bigNumber = 123456789n;
const bigDecimal = 1234.12345;

console.log(inspect(thousand, { numericSeparator: true }));
// 1_000
console.log(inspect(million, { numericSeparator: true }));
// 1_000_000
console.log(inspect(bigNumber, { numericSeparator: true }));
// 123_456_789n
console.log(inspect(bigDecimal, { numericSeparator: true }));
// 1_234.123_45const { inspect } = require('node:util');

const thousand = 1000;
const million = 1000000;
const bigNumber = 123456789n;
const bigDecimal = 1234.12345;

console.log(inspect(thousand, { numericSeparator: true }));
// 1_000
console.log(inspect(million, { numericSeparator: true }));
// 1_000_000
console.log(inspect(bigNumber, { numericSeparator: true }));
// 123_456_789n
console.log(inspect(bigDecimal, { numericSeparator: true }));
// 1_234.123_45

`util.inspect()` 是一个用于调试的同步方法。其最大输出长度约为 128 MiB。导致更长输出的输入将被截断。

自定义 `util.inspect` 颜色#

`util.inspect` 的颜色输出(如果启用)可以通过 `util.inspect.styles` 和 `util.inspect.colors` 属性进行全局自定义。

`util.inspect.styles` 是一个将样式名称与 `util.inspect.colors` 中的颜色关联起来的映射。

默认样式和关联颜色是:

  • bigint: `yellow`
  • boolean: `yellow`
  • date: `magenta`
  • module: `underline`
  • name: (无样式)
  • null: `bold`
  • number: `yellow`
  • regexp: 一个为字符类、组、断言和其他部分着色以提高可读性的方法。要自定义着色,请更改 `colors` 属性。它默认设置为 `['red', 'green', 'yellow', 'cyan', 'magenta']`,并可根据需要进行调整。该数组会根据“深度”重复迭代。
  • special: `cyan` (例如, `Proxies`)
  • string: `green`
  • symbol: `green`
  • undefined: `grey`

颜色样式使用 ANSI 控制码,可能并非所有终端都支持。要验证颜色支持,请使用 `tty.hasColors()`

预定义的控制码如下所列(分组为“修饰符”、“前景色”和“背景色”)。

复杂的自定义着色#

可以将一个方法定义为样式。它接收输入的字符串化值。当着色处于活动状态且该类型被检查时,该方法会被调用。

示例:`util.inspect.styles.regexp(value)`

  • value <string> 输入类型的字符串表示。
  • 返回:<string> `object` 的调整后表示。
修饰符#

不同终端对修饰符的支持各不相同。如果不支持,它们大多会被忽略。

  • reset - 将所有(颜色)修饰符重置为默认值
  • bold - 使文本加粗
  • italic - 使文本变为斜体
  • underline - 为文本添加下划线
  • strikethrough - 在文本中间画一条横线(别名:`strikeThrough`, `crossedout`, `crossedOut`)
  • hidden - 打印文本,但使其不可见(别名:conceal)
  • dim - 降低颜色强度(别名:`faint`)
  • overlined - 为文本添加上划线
  • blink - 按一定间隔隐藏和显示文本
  • inverse - 交换前景色和背景色(别名:`swapcolors`, `swapColors`)
  • doubleunderline - 为文本添加双下划线(别名:`doubleUnderline`)
  • framed - 在文本周围绘制一个边框
前景色#
  • black
  • red
  • green
  • yellow
  • blue
  • magenta
  • cyan
  • white
  • gray (别名: grey, blackBright)
  • redBright
  • greenBright
  • yellowBright
  • blueBright
  • magentaBright
  • cyanBright
  • whiteBright
背景色#
  • bgBlack
  • bgRed
  • bgGreen
  • bgYellow
  • bgBlue
  • bgMagenta
  • bgCyan
  • bgWhite
  • bgGray (别名: bgGrey, bgBlackBright)
  • bgRedBright
  • bgGreenBright
  • bgYellowBright
  • bgBlueBright
  • bgMagentaBright
  • bgCyanBright
  • bgWhiteBright

对象上的自定义检查函数#

对象也可以定义自己的 `[util.inspect.custom](depth, opts, inspect)` 函数,`util.inspect()` 在检查该对象时会调用此函数并使用其返回结果。

import { inspect } from 'node:util';

class Box {
  constructor(value) {
    this.value = value;
  }

  [inspect.custom](depth, options, inspect) {
    if (depth < 0) {
      return options.stylize('[Box]', 'special');
    }

    const newOptions = Object.assign({}, options, {
      depth: options.depth === null ? null : options.depth - 1,
    });

    // Five space padding because that's the size of "Box< ".
    const padding = ' '.repeat(5);
    const inner = inspect(this.value, newOptions)
                  .replace(/\n/g, `\n${padding}`);
    return `${options.stylize('Box', 'special')}< ${inner} >`;
  }
}

const box = new Box(true);

console.log(inspect(box));
// "Box< true >"const { inspect } = require('node:util');

class Box {
  constructor(value) {
    this.value = value;
  }

  [inspect.custom](depth, options, inspect) {
    if (depth < 0) {
      return options.stylize('[Box]', 'special');
    }

    const newOptions = Object.assign({}, options, {
      depth: options.depth === null ? null : options.depth - 1,
    });

    // Five space padding because that's the size of "Box< ".
    const padding = ' '.repeat(5);
    const inner = inspect(this.value, newOptions)
                  .replace(/\n/g, `\n${padding}`);
    return `${options.stylize('Box', 'special')}< ${inner} >`;
  }
}

const box = new Box(true);

console.log(inspect(box));
// "Box< true >"

自定义的 `[util.inspect.custom](depth, opts, inspect)` 函数通常返回一个字符串,但也可以返回任何类型的值,`util.inspect()` 会相应地对其进行格式化。

import { inspect } from 'node:util';

const obj = { foo: 'this will not show up in the inspect() output' };
obj[inspect.custom] = (depth) => {
  return { bar: 'baz' };
};

console.log(inspect(obj));
// "{ bar: 'baz' }"const { inspect } = require('node:util');

const obj = { foo: 'this will not show up in the inspect() output' };
obj[inspect.custom] = (depth) => {
  return { bar: 'baz' };
};

console.log(inspect(obj));
// "{ bar: 'baz' }"

util.inspect.custom#

  • 类型:<symbol> 可用于声明自定义检查函数。

除了可以通过 `util.inspect.custom` 访问外,此符号是全局注册的,可以在任何环境中作为 `Symbol.for('nodejs.util.inspect.custom')` 访问。

使用这个符号可以编写可移植的代码,使得自定义检查函数在 Node.js 环境中使用,而在浏览器中被忽略。`util.inspect()` 函数本身作为第三个参数传递给自定义检查函数,以允许进一步的可移植性。

const customInspectSymbol = Symbol.for('nodejs.util.inspect.custom');

class Password {
  constructor(value) {
    this.value = value;
  }

  toString() {
    return 'xxxxxxxx';
  }

  [customInspectSymbol](depth, inspectOptions, inspect) {
    return `Password <${this.toString()}>`;
  }
}

const password = new Password('r0sebud');
console.log(password);
// Prints Password <xxxxxxxx> 

更多细节请参见对象上的自定义检查函数

util.inspect.defaultOptions#

`defaultOptions` 值允许自定义 `util.inspect` 使用的默认选项。这对于像 `console.log` 或 `util.format` 这样隐式调用 `util.inspect` 的函数很有用。它应被设置为一个包含一个或多个有效 `util.inspect()` 选项的对象。也支持直接设置选项属性。

import { inspect } from 'node:util';
const arr = Array(156).fill(0);

console.log(arr); // Logs the truncated array
inspect.defaultOptions.maxArrayLength = null;
console.log(arr); // logs the full arrayconst { inspect } = require('node:util');
const arr = Array(156).fill(0);

console.log(arr); // Logs the truncated array
inspect.defaultOptions.maxArrayLength = null;
console.log(arr); // logs the full array

util.isDeepStrictEqual(val1, val2[, options])#

  • val1 <any>
  • val2 <any>
  • skipPrototype <boolean> 如果为 `true`,则在深度严格相等检查期间跳过原型和构造函数的比较。默认值: `false`。
  • 返回:<boolean>

如果 `val1` 和 `val2` 之间存在深度严格相等,则返回 `true`。否则,返回 `false`。

默认情况下,深度严格相等包括对象原型和构造函数的比较。当 `skipPrototype` 为 `true` 时,即使对象的原型或构造函数不同,如果它们的可枚举属性是深度严格相等的,它们仍然可以被认为是相等的。

const util = require('node:util');

class Foo {
  constructor(a) {
    this.a = a;
  }
}

class Bar {
  constructor(a) {
    this.a = a;
  }
}

const foo = new Foo(1);
const bar = new Bar(1);

// Different constructors, same properties
console.log(util.isDeepStrictEqual(foo, bar));
// false

console.log(util.isDeepStrictEqual(foo, bar, true));
// true 

有关深度严格相等的更多信息,请参见 `assert.deepStrictEqual()`

类:`util.MIMEType`#

MIMEType 类的实现。

根据浏览器约定,`MIMEType` 对象的所有属性都作为类原型上的 getter 和 setter 实现,而不是作为对象本身的数据属性。

MIME 字符串是一个包含多个有意义组件的结构化字符串。解析后,会返回一个 `MIMEType` 对象,其中包含每个组件的属性。

new MIMEType(input)#

  • input <string> 要解析的输入 MIME

通过解析 `input` 创建一个新的 `MIMEType` 对象。

import { MIMEType } from 'node:util';

const myMIME = new MIMEType('text/plain');const { MIMEType } = require('node:util');

const myMIME = new MIMEType('text/plain');

如果 `input` 不是有效的 MIME,将抛出 `TypeError`。请注意,系统会尝试将给定的值强制转换为字符串。例如:

import { MIMEType } from 'node:util';
const myMIME = new MIMEType({ toString: () => 'text/plain' });
console.log(String(myMIME));
// Prints: text/plainconst { MIMEType } = require('node:util');
const myMIME = new MIMEType({ toString: () => 'text/plain' });
console.log(String(myMIME));
// Prints: text/plain

mime.type#

获取和设置 MIME 的类型部分。

import { MIMEType } from 'node:util';

const myMIME = new MIMEType('text/javascript');
console.log(myMIME.type);
// Prints: text
myMIME.type = 'application';
console.log(myMIME.type);
// Prints: application
console.log(String(myMIME));
// Prints: application/javascriptconst { MIMEType } = require('node:util');

const myMIME = new MIMEType('text/javascript');
console.log(myMIME.type);
// Prints: text
myMIME.type = 'application';
console.log(myMIME.type);
// Prints: application
console.log(String(myMIME));
// Prints: application/javascript

mime.subtype#

获取和设置 MIME 的子类型部分。

import { MIMEType } from 'node:util';

const myMIME = new MIMEType('text/ecmascript');
console.log(myMIME.subtype);
// Prints: ecmascript
myMIME.subtype = 'javascript';
console.log(myMIME.subtype);
// Prints: javascript
console.log(String(myMIME));
// Prints: text/javascriptconst { MIMEType } = require('node:util');

const myMIME = new MIMEType('text/ecmascript');
console.log(myMIME.subtype);
// Prints: ecmascript
myMIME.subtype = 'javascript';
console.log(myMIME.subtype);
// Prints: javascript
console.log(String(myMIME));
// Prints: text/javascript

mime.essence#

获取 MIME 的本质部分。此属性为只读。请使用 `mime.type` 或 `mime.subtype` 来修改 MIME。

import { MIMEType } from 'node:util';

const myMIME = new MIMEType('text/javascript;key=value');
console.log(myMIME.essence);
// Prints: text/javascript
myMIME.type = 'application';
console.log(myMIME.essence);
// Prints: application/javascript
console.log(String(myMIME));
// Prints: application/javascript;key=valueconst { MIMEType } = require('node:util');

const myMIME = new MIMEType('text/javascript;key=value');
console.log(myMIME.essence);
// Prints: text/javascript
myMIME.type = 'application';
console.log(myMIME.essence);
// Prints: application/javascript
console.log(String(myMIME));
// Prints: application/javascript;key=value

mime.params#

获取代表 MIME 参数的 `MIMEParams` 对象。此属性为只读。详细信息请参阅 `MIMEParams` 文档。

mime.toString()#

`MIMEType` 对象上的 `toString()` 方法返回序列化后的 MIME。

由于需要符合标准,此方法不允许用户自定义 MIME 的序列化过程。

mime.toJSON()#

`mime.toString()` 的别名。

当 `MIMEType` 对象使用 `JSON.stringify()` 序列化时,会自动调用此方法。

import { MIMEType } from 'node:util';

const myMIMES = [
  new MIMEType('image/png'),
  new MIMEType('image/gif'),
];
console.log(JSON.stringify(myMIMES));
// Prints: ["image/png", "image/gif"]const { MIMEType } = require('node:util');

const myMIMES = [
  new MIMEType('image/png'),
  new MIMEType('image/gif'),
];
console.log(JSON.stringify(myMIMES));
// Prints: ["image/png", "image/gif"]

类:`util.MIMEParams`#

`MIMEParams` API 提供了对 `MIMEType` 参数的读写访问。

new MIMEParams()#

创建一个新的 `MIMEParams` 对象,其参数为空。

import { MIMEParams } from 'node:util';

const myParams = new MIMEParams();const { MIMEParams } = require('node:util');

const myParams = new MIMEParams();

mimeParams.delete(name)#

移除所有名称为 `name` 的键值对。

mimeParams.entries()#

返回一个迭代器,用于遍历参数中的每个键值对。迭代器的每个项目都是一个 JavaScript `Array`。数组的第一个项目是 `name`,第二个项目是 `value`。

mimeParams.get(name)#

  • name <string>
  • 返回:<string> | <null> 一个字符串,如果不存在具有给定 `name` 的键值对,则为 `null`。

返回名称为 `name` 的第一个键值对的值。如果没有这样的键值对,则返回 `null`。

mimeParams.has(name)#

如果至少存在一个名称为 `name` 的键值对,则返回 `true`。

mimeParams.keys()#

返回一个迭代器,用于遍历每个键值对的名称。

import { MIMEType } from 'node:util';

const { params } = new MIMEType('text/plain;foo=0;bar=1');
for (const name of params.keys()) {
  console.log(name);
}
// Prints:
//   foo
//   barconst { MIMEType } = require('node:util');

const { params } = new MIMEType('text/plain;foo=0;bar=1');
for (const name of params.keys()) {
  console.log(name);
}
// Prints:
//   foo
//   bar

mimeParams.set(name, value)#

在 `MIMEParams` 对象中,将与 `name` 关联的值设置为 `value`。如果已存在名称为 `name` 的键值对,则将第一个这样的键值对的值设置为 `value`。

import { MIMEType } from 'node:util';

const { params } = new MIMEType('text/plain;foo=0;bar=1');
params.set('foo', 'def');
params.set('baz', 'xyz');
console.log(params.toString());
// Prints: foo=def;bar=1;baz=xyzconst { MIMEType } = require('node:util');

const { params } = new MIMEType('text/plain;foo=0;bar=1');
params.set('foo', 'def');
params.set('baz', 'xyz');
console.log(params.toString());
// Prints: foo=def;bar=1;baz=xyz

mimeParams.values()#

返回一个迭代器,用于遍历每个键值对的值。

mimeParams[Symbol.iterator]()#

`mimeParams.entries()` 的别名。

import { MIMEType } from 'node:util';

const { params } = new MIMEType('text/plain;foo=bar;xyz=baz');
for (const [name, value] of params) {
  console.log(name, value);
}
// Prints:
//   foo bar
//   xyz bazconst { MIMEType } = require('node:util');

const { params } = new MIMEType('text/plain;foo=bar;xyz=baz');
for (const [name, value] of params) {
  console.log(name, value);
}
// Prints:
//   foo bar
//   xyz baz

util.parseArgs([config])#

  • config <Object> 用于提供解析参数并配置解析器。`config` 支持以下属性:

    • args <string[]> 参数字符串数组。默认值: `process.argv`,移除了 `execPath` 和 `filename`。
    • options <Object> 用于描述解析器已知的参数。`options` 的键是选项的长名称,值是一个<Object>,接受以下属性:
      • type <string> 参数类型,必须是 `boolean` 或 `string`。
      • multiple <boolean> 此选项是否可以多次提供。如果为 `true`,所有值将收集到一个数组中。如果为 `false`,则选项的值为“后者优先”。默认值: `false`。
      • short <string> 选项的单字符别名。
      • default <string> | <boolean> | <string[]> | <boolean[]> 如果选项未出现在待解析的参数中,则分配给该选项的值。该值必须与 `type` 属性指定的类型匹配。如果 `multiple` 为 `true`,则它必须是一个数组。当选项出现在待解析的参数中时,即使提供的值是假值,也不会应用默认值。
    • strict <boolean> 遇到未知参数或传递的参数与 `options` 中配置的 `type` 不匹配时,是否应抛出错误。默认值: `true`。
    • allowPositionals <boolean> 此命令是否接受位置参数。默认值: 如果 `strict` 为 `true`,则为 `false`,否则为 `true`。
    • allowNegative <boolean> 如果为 `true`,则允许通过在选项名前加上 `--no-` 前缀来显式地将布尔选项设置为 `false`。默认值: `false`。
    • tokens <boolean> 返回解析后的令牌(tokens)。这对于扩展内置行为很有用,从添加额外的检查到以不同方式重新处理令牌。默认值: `false`。
  • 返回:<Object> 解析后的命令行参数

提供比直接与 `process.argv` 交互更高层次的命令行参数解析 API。它接受一个预期参数的规范,并返回一个包含已解析选项和位置参数的结构化对象。

import { parseArgs } from 'node:util';
const args = ['-f', '--bar', 'b'];
const options = {
  foo: {
    type: 'boolean',
    short: 'f',
  },
  bar: {
    type: 'string',
  },
};
const {
  values,
  positionals,
} = parseArgs({ args, options });
console.log(values, positionals);
// Prints: [Object: null prototype] { foo: true, bar: 'b' } []const { parseArgs } = require('node:util');
const args = ['-f', '--bar', 'b'];
const options = {
  foo: {
    type: 'boolean',
    short: 'f',
  },
  bar: {
    type: 'string',
  },
};
const {
  values,
  positionals,
} = parseArgs({ args, options });
console.log(values, positionals);
// Prints: [Object: null prototype] { foo: true, bar: 'b' } []

parseArgs 的 `tokens`#

通过在配置中指定 `tokens: true`,可以获取详细的解析信息以添加自定义行为。返回的令牌具有描述以下内容的属性:

  • 所有令牌
    • kind <string> 'option'、'positional' 或 'option-terminator' 之一。
    • index <number> 包含令牌的 `args` 中元素的索引。因此,令牌的源参数是 `args[token.index]`。
  • 选项令牌
    • name <string> 选项的长名称。
    • rawName <string> 选项在 args 中的使用方式,如 `-f` 或 `--foo`。
    • value <string> | <undefined> 在 args 中指定的选项值。对于布尔选项为 undefined。
    • inlineValue <boolean> | <undefined> 选项值是否内联指定,如 `--foo=bar`。
  • 位置令牌
    • value <string> args 中位置参数的值(即 `args[index]`)。
  • 选项终止符令牌

返回的令牌按其在输入 args 中出现的顺序排列。在 args 中出现多次的选项会为每次使用生成一个令牌。短选项组(如 `-xy`)会扩展为每个选项一个令牌。所以 `-xxx` 会产生三个令牌。

例如,要添加对否定选项(如 `--no-color`,`allowNegative` 在选项为 `boolean` 类型时支持)的支持,可以重新处理返回的令牌来更改为否定选项存储的值。

import { parseArgs } from 'node:util';

const options = {
  'color': { type: 'boolean' },
  'no-color': { type: 'boolean' },
  'logfile': { type: 'string' },
  'no-logfile': { type: 'boolean' },
};
const { values, tokens } = parseArgs({ options, tokens: true });

// Reprocess the option tokens and overwrite the returned values.
tokens
  .filter((token) => token.kind === 'option')
  .forEach((token) => {
    if (token.name.startsWith('no-')) {
      // Store foo:false for --no-foo
      const positiveName = token.name.slice(3);
      values[positiveName] = false;
      delete values[token.name];
    } else {
      // Resave value so last one wins if both --foo and --no-foo.
      values[token.name] = token.value ?? true;
    }
  });

const color = values.color;
const logfile = values.logfile ?? 'default.log';

console.log({ logfile, color });const { parseArgs } = require('node:util');

const options = {
  'color': { type: 'boolean' },
  'no-color': { type: 'boolean' },
  'logfile': { type: 'string' },
  'no-logfile': { type: 'boolean' },
};
const { values, tokens } = parseArgs({ options, tokens: true });

// Reprocess the option tokens and overwrite the returned values.
tokens
  .filter((token) => token.kind === 'option')
  .forEach((token) => {
    if (token.name.startsWith('no-')) {
      // Store foo:false for --no-foo
      const positiveName = token.name.slice(3);
      values[positiveName] = false;
      delete values[token.name];
    } else {
      // Resave value so last one wins if both --foo and --no-foo.
      values[token.name] = token.value ?? true;
    }
  });

const color = values.color;
const logfile = values.logfile ?? 'default.log';

console.log({ logfile, color });

示例用法展示了否定选项,以及当一个选项以多种方式使用时,最后一个会生效。

$ node negate.js
{ logfile: 'default.log', color: undefined }
$ node negate.js --no-logfile --no-color
{ logfile: false, color: false }
$ node negate.js --logfile=test.log --color
{ logfile: 'test.log', color: true }
$ node negate.js --no-logfile --logfile=test.log --color --no-color
{ logfile: 'test.log', color: false } 

util.parseEnv(content)#

一个 `.env` 文件的原始内容。

给定一个示例 `.env` 文件:

const { parseEnv } = require('node:util');

parseEnv('HELLO=world\nHELLO=oh my\n');
// Returns: { HELLO: 'oh my' }import { parseEnv } from 'node:util';

parseEnv('HELLO=world\nHELLO=oh my\n');
// Returns: { HELLO: 'oh my' }

util.promisify(original)#

接受一个遵循常见的错误优先回调风格的函数(即最后一个参数是 `(err, value) => ...` 回调),并返回一个返回 promise 的版本。

import { promisify } from 'node:util';
import { stat } from 'node:fs';

const promisifiedStat = promisify(stat);
promisifiedStat('.').then((stats) => {
  // Do something with `stats`
}).catch((error) => {
  // Handle the error.
});const { promisify } = require('node:util');
const { stat } = require('node:fs');

const promisifiedStat = promisify(stat);
promisifiedStat('.').then((stats) => {
  // Do something with `stats`
}).catch((error) => {
  // Handle the error.
});

或者,等效地使用 `async function`s:

import { promisify } from 'node:util';
import { stat } from 'node:fs';

const promisifiedStat = promisify(stat);

async function callStat() {
  const stats = await promisifiedStat('.');
  console.log(`This directory is owned by ${stats.uid}`);
}

callStat();const { promisify } = require('node:util');
const { stat } = require('node:fs');

const promisifiedStat = promisify(stat);

async function callStat() {
  const stats = await promisifiedStat('.');
  console.log(`This directory is owned by ${stats.uid}`);
}

callStat();

如果存在 `original[util.promisify.custom]` 属性,`promisify` 将返回其值,参见自定义 promisified 函数

`promisify()` 假定在所有情况下,`original` 都是一个以回调作为其最后一个参数的函数。如果 `original` 不是一个函数,`promisify()` 将抛出一个错误。如果 `original` 是一个函数,但其最后一个参数不是一个错误优先的回调,它仍然会被传递一个错误优先的回调作为其最后一个参数。

在类方法或其他使用 `this` 的方法上使用 `promisify()` 可能不会按预期工作,除非进行特殊处理:

import { promisify } from 'node:util';

class Foo {
  constructor() {
    this.a = 42;
  }

  bar(callback) {
    callback(null, this.a);
  }
}

const foo = new Foo();

const naiveBar = promisify(foo.bar);
// TypeError: Cannot read properties of undefined (reading 'a')
// naiveBar().then(a => console.log(a));

naiveBar.call(foo).then((a) => console.log(a)); // '42'

const bindBar = naiveBar.bind(foo);
bindBar().then((a) => console.log(a)); // '42'const { promisify } = require('node:util');

class Foo {
  constructor() {
    this.a = 42;
  }

  bar(callback) {
    callback(null, this.a);
  }
}

const foo = new Foo();

const naiveBar = promisify(foo.bar);
// TypeError: Cannot read properties of undefined (reading 'a')
// naiveBar().then(a => console.log(a));

naiveBar.call(foo).then((a) => console.log(a)); // '42'

const bindBar = naiveBar.bind(foo);
bindBar().then((a) => console.log(a)); // '42'

自定义 promisified 函数#

使用 `util.promisify.custom` 符号可以覆盖 `util.promisify()` 的返回值:

import { promisify } from 'node:util';

function doSomething(foo, callback) {
  // ...
}

doSomething[promisify.custom] = (foo) => {
  return getPromiseSomehow();
};

const promisified = promisify(doSomething);
console.log(promisified === doSomething[promisify.custom]);
// prints 'true'const { promisify } = require('node:util');

function doSomething(foo, callback) {
  // ...
}

doSomething[promisify.custom] = (foo) => {
  return getPromiseSomehow();
};

const promisified = promisify(doSomething);
console.log(promisified === doSomething[promisify.custom]);
// prints 'true'

这对于原始函数不遵循将错误优先回调作为最后一个参数的标准格式的情况可能很有用。

例如,对于一个接受 `(foo, onSuccessCallback, onErrorCallback)` 的函数:

doSomething[util.promisify.custom] = (foo) => {
  return new Promise((resolve, reject) => {
    doSomething(foo, resolve, reject);
  });
}; 

如果定义了 `promisify.custom` 但它不是一个函数,`promisify()` 将抛出一个错误。

util.promisify.custom#

除了可以通过 `util.promisify.custom` 访问外,此符号是全局注册的,可以在任何环境中作为 `Symbol.for('nodejs.util.promisify.custom')` 访问。

例如,对于一个接受 `(foo, onSuccessCallback, onErrorCallback)` 的函数:

const kCustomPromisifiedSymbol = Symbol.for('nodejs.util.promisify.custom');

doSomething[kCustomPromisifiedSymbol] = (foo) => {
  return new Promise((resolve, reject) => {
    doSomething(foo, resolve, reject);
  });
}; 

util.stripVTControlCharacters(str)#

返回移除了所有 ANSI 转义码的 `str`。

console.log(util.stripVTControlCharacters('\u001B[4mvalue\u001B[0m'));
// Prints "value" 

util.styleText(format, text[, options])#

  • format <string> | <Array> 一个文本格式或在 `util.inspect.colors` 中定义的文本格式数组。
  • text <string> 要格式化的文本。
  • options <Object>
    • validateStream <boolean> 当为 true 时,会检查 `stream` 是否能处理颜色。默认值: `true`。
    • stream <Stream> 一个将验证其是否可以着色的流。默认值: `process.stdout`。

此函数返回一个格式化的文本,考虑了传入的 `format`,用于在终端中打印。它能感知终端的功能,并根据通过 `NO_COLOR`、`NODE_DISABLE_COLORS` 和 `FORCE_COLOR` 环境变量设置的配置来行动。

import { styleText } from 'node:util';
import { stderr } from 'node:process';

const successMessage = styleText('green', 'Success!');
console.log(successMessage);

const errorMessage = styleText(
  'red',
  'Error! Error!',
  // Validate if process.stderr has TTY
  { stream: stderr },
);
console.error(errorMessage);const { styleText } = require('node:util');
const { stderr } = require('node:process');

const successMessage = styleText('green', 'Success!');
console.log(successMessage);

const errorMessage = styleText(
  'red',
  'Error! Error!',
  // Validate if process.stderr has TTY
  { stream: stderr },
);
console.error(errorMessage);

`util.inspect.colors` 也提供了诸如 `italic` 和 `underline` 的文本格式,您可以将两者结合起来:

console.log(
  util.styleText(['underline', 'italic'], 'My italic underlined message'),
); 

当传递一个格式数组时,格式的应用顺序是从左到右,所以后面的样式可能会覆盖前面的样式。

console.log(
  util.styleText(['red', 'green'], 'text'), // green
); 

特殊的格式值 `none` 不会对文本应用任何额外的样式。

完整的格式列表可以在修饰符中找到。

类:`util.TextDecoder`#

WHATWG 编码标准 `TextDecoder` API 的实现。

const decoder = new TextDecoder();
const u8arr = new Uint8Array([72, 101, 108, 108, 111]);
console.log(decoder.decode(u8arr)); // Hello 

WHATWG 支持的编码#

根据 WHATWG 编码标准,`TextDecoder` API 支持的编码如下表所示。对于每种编码,可以使用一个或多个别名。

不同的 Node.js 构建配置支持不同的编码集。(参见 国际化

默认支持的编码(使用完整的 ICU 数据)#
编码别名
'ibm866''866', 'cp866', 'csibm866'
'iso-8859-2''csisolatin2', 'iso-ir-101', 'iso8859-2', 'iso88592', 'iso_8859-2', 'iso_8859-2:1987', 'l2', 'latin2'
'iso-8859-3''csisolatin3', 'iso-ir-109', 'iso8859-3', 'iso88593', 'iso_8859-3', 'iso_8859-3:1988', 'l3', 'latin3'
'iso-8859-4''csisolatin4', 'iso-ir-110', 'iso8859-4', 'iso88594', 'iso_8859-4', 'iso_8859-4:1988', 'l4', 'latin4'
'iso-8859-5''csisolatincyrillic', 'cyrillic', 'iso-ir-144', 'iso8859-5', 'iso88595', 'iso_8859-5', 'iso_8859-5:1988'
'iso-8859-6''arabic', 'asmo-708', 'csiso88596e', 'csiso88596i', 'csisolatinarabic', 'ecma-114', 'iso-8859-6-e', 'iso-8859-6-i', 'iso-ir-127', 'iso8859-6', 'iso88596', 'iso_8859-6', 'iso_8859-6:1987'
'iso-8859-7''csisolatingreek', 'ecma-118', 'elot_928', 'greek', 'greek8', 'iso-ir-126', 'iso8859-7', 'iso88597', 'iso_8859-7', 'iso_8859-7:1987', 'sun_eu_greek'
'iso-8859-8''csiso88598e', 'csisolatinhebrew', 'hebrew', 'iso-8859-8-e', 'iso-ir-138', 'iso8859-8', 'iso88598', 'iso_8859-8', 'iso_8859-8:1988', 'visual'
'iso-8859-8-i''csiso88598i', 'logical'
'iso-8859-10''csisolatin6', 'iso-ir-157', 'iso8859-10', 'iso885910', 'l6', 'latin6'
'iso-8859-13''iso8859-13', 'iso885913'
'iso-8859-14''iso8859-14', 'iso885914'
'iso-8859-15''csisolatin9', 'iso8859-15', 'iso885915', 'iso_8859-15', 'l9'
'koi8-r''cskoi8r', 'koi', 'koi8', 'koi8_r'
'koi8-u''koi8-ru'
'macintosh''csmacintosh', 'mac', 'x-mac-roman'
'windows-874''dos-874', 'iso-8859-11', 'iso8859-11', 'iso885911', 'tis-620'
'windows-1250''cp1250', 'x-cp1250'
'windows-1251''cp1251', 'x-cp1251'
'windows-1252''ansi_x3.4-1968', 'ascii', 'cp1252', 'cp819', 'csisolatin1', 'ibm819', 'iso-8859-1', 'iso-ir-100', 'iso8859-1', 'iso88591', 'iso_8859-1', 'iso_8859-1:1987', 'l1', 'latin1', 'us-ascii', 'x-cp1252'
'windows-1253''cp1253', 'x-cp1253'
'windows-1254''cp1254', 'csisolatin5', 'iso-8859-9', 'iso-ir-148', 'iso8859-9', 'iso88599', 'iso_8859-9', 'iso_8859-9:1989', 'l5', 'latin5', 'x-cp1254'
'windows-1255''cp1255', 'x-cp1255'
'windows-1256''cp1256', 'x-cp1256'
'windows-1257''cp1257', 'x-cp1257'
'windows-1258''cp1258', 'x-cp1258'
'x-mac-cyrillic''x-mac-ukrainian'
'gbk''chinese', 'csgb2312', 'csiso58gb231280', 'gb2312', 'gb_2312', 'gb_2312-80', 'iso-ir-58', 'x-gbk'
'gb18030'
'big5''big5-hkscs', 'cn-big5', 'csbig5', 'x-x-big5'
'euc-jp''cseucpkdfmtjapanese', 'x-euc-jp'
'iso-2022-jp''csiso2022jp'
'shift_jis''csshiftjis', 'ms932', 'ms_kanji', 'shift-jis', 'sjis', 'windows-31j', 'x-sjis'
'euc-kr''cseuckr', 'csksc56011987', 'iso-ir-149', 'korean', 'ks_c_5601-1987', 'ks_c_5601-1989', 'ksc5601', 'ksc_5601', 'windows-949'
使用 small-icu 选项构建 Node.js 时支持的编码#
编码别名
'utf-8''unicode-1-1-utf-8', 'utf8'
'utf-16le''utf-16'
'utf-16be'
禁用 ICU 时支持的编码#
编码别名
'utf-8''unicode-1-1-utf-8', 'utf8'
'utf-16le''utf-16'

不支持 WHATWG 编码标准 中列出的 'iso-8859-16' 编码。

new TextDecoder([encoding[, options]])#

  • encoding <string> 标识此 TextDecoder 实例支持的 encoding默认值: 'utf-8'
  • options <Object>
    • fatal <boolean> 如果解码失败是致命的,则为 true。禁用 ICU 时不支持此选项(参见 国际化)。默认值: false
    • ignoreBOM <boolean> 当为 true 时,TextDecoder 将在解码结果中包含字节顺序标记(BOM)。当为 false 时,字节顺序标记将从输出中移除。此选项仅在 encoding'utf-8''utf-16be''utf-16le' 时使用。默认值: false

创建一个新的 TextDecoder 实例。encoding 可以指定支持的编码之一或其别名。

TextDecoder 类也可在全局对象上使用。

textDecoder.decode([input[, options]])#

解码 input 并返回一个字符串。如果 options.streamtrue,任何出现在 input 末尾的不完整字节序列都会被内部缓冲,并在下一次调用 textDecoder.decode() 后发出。

如果 textDecoder.fataltrue,发生的解码错误将导致抛出 TypeError

textDecoder.encoding#

TextDecoder 实例支持的编码。

textDecoder.fatal#

如果解码错误导致抛出 TypeError,该值将为 true

textDecoder.ignoreBOM#

如果解码结果将包含字节顺序标记,则该值为 true

类:util.TextEncoder#

WHATWG 编码标准 TextEncoder API 的实现。所有 TextEncoder 实例仅支持 UTF-8 编码。

const encoder = new TextEncoder();
const uint8array = encoder.encode('this is some data'); 

TextEncoder 类也可在全局对象上使用。

textEncoder.encode([input])#

input 字符串进行 UTF-8 编码,并返回一个包含编码后字节的 Uint8Array

textEncoder.encodeInto(src, dest)#

  • src <string> 要编码的文本。
  • dest <Uint8Array> 用于存放编码结果的数组。
  • 返回:<Object>
    • read <number> 从 src 读取的 Unicode 码元数量。
    • written <number> 写入到 dest 的 UTF-8 字节数。

src 字符串进行 UTF-8 编码到 dest Uint8Array 中,并返回一个包含已读取的 Unicode 码元数和已写入的 UTF-8 字节数的对象。

const encoder = new TextEncoder();
const src = 'this is some data';
const dest = new Uint8Array(10);
const { read, written } = encoder.encodeInto(src, dest); 

textEncoder.encoding#

TextEncoder 实例支持的编码。始终设置为 'utf-8'

util.toUSVString(string)#

返回将任何代理码点(或等效地,任何未配对的代理码元)替换为 Unicode“替换字符”U+FFFD 后的 string

util.transferableAbortController()#

创建并返回一个 <AbortController> 实例,其 <AbortSignal> 被标记为可传输,并且可以与 structuredClone()postMessage() 一起使用。

util.transferableAbortSignal(signal)#

将给定的 <AbortSignal> 标记为可传输,以便它可以与 structuredClone()postMessage() 一起使用。

const signal = transferableAbortSignal(AbortSignal.timeout(100));
const channel = new MessageChannel();
channel.port2.postMessage(signal, [signal]); 

util.aborted(signal, resource)#

  • signal <AbortSignal>
  • resource <Object> 任何与可中止操作相关联且被弱引用的非空对象。如果 resourcesignal 中止之前被垃圾回收,则 promise 保持待定状态,从而允许 Node.js 停止跟踪它。这有助于防止在长时间运行或不可取消的操作中出现内存泄漏。
  • 返回:<Promise>

监听所提供 signal 上的中止事件,并返回一个在 signal 中止时解析的 promise。如果提供了 resource,它会弱引用操作的关联对象,因此如果 resourcesignal 中止之前被垃圾回收,那么返回的 promise 将保持待定状态。这可以防止在长时间运行或不可取消的操作中出现内存泄漏。

const { aborted } = require('node:util');

// Obtain an object with an abortable signal, like a custom resource or operation.
const dependent = obtainSomethingAbortable();

// Pass `dependent` as the resource, indicating the promise should only resolve
// if `dependent` is still in memory when the signal is aborted.
aborted(dependent.signal, dependent).then(() => {

  // This code runs when `dependent` is aborted.
  console.log('Dependent resource was aborted.');
});

// Simulate an event that triggers the abort.
dependent.on('event', () => {
  dependent.abort(); // This will cause the `aborted` promise to resolve.
});import { aborted } from 'node:util';

// Obtain an object with an abortable signal, like a custom resource or operation.
const dependent = obtainSomethingAbortable();

// Pass `dependent` as the resource, indicating the promise should only resolve
// if `dependent` is still in memory when the signal is aborted.
aborted(dependent.signal, dependent).then(() => {

  // This code runs when `dependent` is aborted.
  console.log('Dependent resource was aborted.');
});

// Simulate an event that triggers the abort.
dependent.on('event', () => {
  dependent.abort(); // This will cause the `aborted` promise to resolve.
});

util.types#

util.types 为不同类型的内置对象提供类型检查。与 instanceofObject.prototype.toString.call(value) 不同,这些检查不检查可从 JavaScript 访问的对象属性(如它们的原型),并且通常有调用到 C++ 的开销。

其结果通常不保证一个值在 JavaScript 中暴露了哪些类型的属性或行为。它们主要对希望在 JavaScript 中进行类型检查的插件开发者有用。

该 API 可通过 require('node:util').typesrequire('node:util/types') 访问。

util.types.isAnyArrayBuffer(value)#

如果值是内置的 <ArrayBuffer><SharedArrayBuffer> 实例,则返回 true

另请参见 util.types.isArrayBuffer()util.types.isSharedArrayBuffer()

util.types.isAnyArrayBuffer(new ArrayBuffer());  // Returns true
util.types.isAnyArrayBuffer(new SharedArrayBuffer());  // Returns true 

util.types.isArrayBufferView(value)#

如果值是 <ArrayBuffer> 视图之一的实例(如类型化数组对象或 <DataView>),则返回 true。等同于 ArrayBuffer.isView()

util.types.isArrayBufferView(new Int8Array());  // true
util.types.isArrayBufferView(Buffer.from('hello world')); // true
util.types.isArrayBufferView(new DataView(new ArrayBuffer(16)));  // true
util.types.isArrayBufferView(new ArrayBuffer());  // false 

util.types.isArgumentsObject(value)#

如果值是 arguments 对象,则返回 true

function foo() {
  util.types.isArgumentsObject(arguments);  // Returns true
} 

util.types.isArrayBuffer(value)#

如果值是内置的 <ArrayBuffer> 实例,则返回 true。这包括 <SharedArrayBuffer> 实例。通常情况下,期望同时测试两者;请参见 util.types.isAnyArrayBuffer()

util.types.isArrayBuffer(new ArrayBuffer());  // Returns true
util.types.isArrayBuffer(new SharedArrayBuffer());  // Returns false 

util.types.isAsyncFunction(value)#

如果值是异步函数,则返回 true。这只报告 JavaScript 引擎看到的情况;特别地,如果使用了转译工具,返回值可能与原始源代码不匹配。

util.types.isAsyncFunction(function foo() {});  // Returns false
util.types.isAsyncFunction(async function foo() {});  // Returns true 

util.types.isBigInt64Array(value)#

如果值是 BigInt64Array 实例,则返回 true

util.types.isBigInt64Array(new BigInt64Array());   // Returns true
util.types.isBigInt64Array(new BigUint64Array());  // Returns false 

util.types.isBigIntObject(value)#

如果该值是 BigInt 对象(例如,通过 Object(BigInt(123)) 创建),则返回 true

util.types.isBigIntObject(Object(BigInt(123)));   // Returns true
util.types.isBigIntObject(BigInt(123));   // Returns false
util.types.isBigIntObject(123);  // Returns false 

util.types.isBigUint64Array(value)#

如果值是 BigUint64Array 实例,则返回 true

util.types.isBigUint64Array(new BigInt64Array());   // Returns false
util.types.isBigUint64Array(new BigUint64Array());  // Returns true 

util.types.isBooleanObject(value)#

如果该值是布尔对象(例如,通过 new Boolean() 创建),则返回 true

util.types.isBooleanObject(false);  // Returns false
util.types.isBooleanObject(true);   // Returns false
util.types.isBooleanObject(new Boolean(false)); // Returns true
util.types.isBooleanObject(new Boolean(true));  // Returns true
util.types.isBooleanObject(Boolean(false)); // Returns false
util.types.isBooleanObject(Boolean(true));  // Returns false 

util.types.isBoxedPrimitive(value)#

如果该值是任何包装过的原始类型对象(例如,通过 new Boolean()new String()Object(Symbol()) 创建),则返回 true

例如:

util.types.isBoxedPrimitive(false); // Returns false
util.types.isBoxedPrimitive(new Boolean(false)); // Returns true
util.types.isBoxedPrimitive(Symbol('foo')); // Returns false
util.types.isBoxedPrimitive(Object(Symbol('foo'))); // Returns true
util.types.isBoxedPrimitive(Object(BigInt(5))); // Returns true 

util.types.isCryptoKey(value)#

如果 value 是一个 <CryptoKey>,则返回 true,否则返回 false

util.types.isDataView(value)#

如果值是内置的 <DataView> 实例,则返回 true

const ab = new ArrayBuffer(20);
util.types.isDataView(new DataView(ab));  // Returns true
util.types.isDataView(new Float64Array());  // Returns false 

另请参见 ArrayBuffer.isView()

util.types.isDate(value)#

如果值是内置的 <Date> 实例,则返回 true

util.types.isDate(new Date());  // Returns true 

util.types.isExternal(value)#

如果值是原生的 External 值,则返回 true

原生 External 值是一种特殊类型的对象,它包含一个原始 C++ 指针(void*)供原生代码访问,并且没有其他属性。这类对象由 Node.js 内部或原生插件创建。在 JavaScript 中,它们是原型为 null冻结对象。

#include <js_native_api.h>
#include <stdlib.h>
napi_value result;
static napi_value MyNapi(napi_env env, napi_callback_info info) {
  int* raw = (int*) malloc(1024);
  napi_status status = napi_create_external(env, (void*) raw, NULL, NULL, &result);
  if (status != napi_ok) {
    napi_throw_error(env, NULL, "napi_create_external failed");
    return NULL;
  }
  return result;
}
...
DECLARE_NAPI_PROPERTY("myNapi", MyNapi)
... 
import native from 'napi_addon.node';
import { types } from 'node:util';

const data = native.myNapi();
types.isExternal(data); // returns true
types.isExternal(0); // returns false
types.isExternal(new String('foo')); // returns falseconst native = require('napi_addon.node');
const { types } = require('node:util');

const data = native.myNapi();
types.isExternal(data); // returns true
types.isExternal(0); // returns false
types.isExternal(new String('foo')); // returns false

关于 napi_create_external 的更多信息,请参考 napi_create_external()

util.types.isFloat16Array(value)#

如果值是内置的 <Float16Array> 实例,则返回 true

util.types.isFloat16Array(new ArrayBuffer());  // Returns false
util.types.isFloat16Array(new Float16Array());  // Returns true
util.types.isFloat16Array(new Float32Array());  // Returns false 

util.types.isFloat32Array(value)#

如果值是内置的 <Float32Array> 实例,则返回 true

util.types.isFloat32Array(new ArrayBuffer());  // Returns false
util.types.isFloat32Array(new Float32Array());  // Returns true
util.types.isFloat32Array(new Float64Array());  // Returns false 

util.types.isFloat64Array(value)#

如果值是内置的 <Float64Array> 实例,则返回 true

util.types.isFloat64Array(new ArrayBuffer());  // Returns false
util.types.isFloat64Array(new Uint8Array());  // Returns false
util.types.isFloat64Array(new Float64Array());  // Returns true 

util.types.isGeneratorFunction(value)#

如果值是生成器函数,则返回 true。这只报告 JavaScript 引擎看到的情况;特别地,如果使用了转译工具,返回值可能与原始源代码不匹配。

util.types.isGeneratorFunction(function foo() {});  // Returns false
util.types.isGeneratorFunction(function* foo() {});  // Returns true 

util.types.isGeneratorObject(value)#

如果值是从内置生成器函数返回的生成器对象,则返回 true。这只报告 JavaScript 引擎看到的情况;特别地,如果使用了转译工具,返回值可能与原始源代码不匹配。

function* foo() {}
const generator = foo();
util.types.isGeneratorObject(generator);  // Returns true 

util.types.isInt8Array(value)#

如果值是内置的 <Int8Array> 实例,则返回 true

util.types.isInt8Array(new ArrayBuffer());  // Returns false
util.types.isInt8Array(new Int8Array());  // Returns true
util.types.isInt8Array(new Float64Array());  // Returns false 

util.types.isInt16Array(value)#

如果值是内置的 <Int16Array> 实例,则返回 true

util.types.isInt16Array(new ArrayBuffer());  // Returns false
util.types.isInt16Array(new Int16Array());  // Returns true
util.types.isInt16Array(new Float64Array());  // Returns false 

util.types.isInt32Array(value)#

如果值是内置的 <Int32Array> 实例,则返回 true

util.types.isInt32Array(new ArrayBuffer());  // Returns false
util.types.isInt32Array(new Int32Array());  // Returns true
util.types.isInt32Array(new Float64Array());  // Returns false 

util.types.isKeyObject(value)#

如果 value 是一个 <KeyObject>,则返回 true,否则返回 false

util.types.isMap(value)#

如果值是内置的 <Map> 实例,则返回 true

util.types.isMap(new Map());  // Returns true 

util.types.isMapIterator(value)#

如果值是为内置 <Map> 实例返回的迭代器,则返回 true

const map = new Map();
util.types.isMapIterator(map.keys());  // Returns true
util.types.isMapIterator(map.values());  // Returns true
util.types.isMapIterator(map.entries());  // Returns true
util.types.isMapIterator(map[Symbol.iterator]());  // Returns true 

util.types.isModuleNamespaceObject(value)#

如果值是模块命名空间对象的实例,则返回 true

import * as ns from './a.js';

util.types.isModuleNamespaceObject(ns);  // Returns true 

util.types.isNativeError(value)#

稳定性:0 - 已弃用:请改用 Error.isError

注意: 自 Node.js v24 起,Error.isError() 目前比 util.types.isNativeError() 慢。如果性能至关重要,请考虑在您的环境中对两者进行基准测试。

如果该值是由内置 Error 类型的构造函数返回的,则返回 true

console.log(util.types.isNativeError(new Error()));  // true
console.log(util.types.isNativeError(new TypeError()));  // true
console.log(util.types.isNativeError(new RangeError()));  // true 

原生错误类型的子类也是原生错误

class MyError extends Error {}
console.log(util.types.isNativeError(new MyError()));  // true 

一个值是原生错误类的 instanceof 并不等同于 isNativeError() 对该值返回 trueisNativeError() 对来自不同领域的错误返回 true,而 instanceof Error 对这些错误返回 false

import { createContext, runInContext } from 'node:vm';
import { types } from 'node:util';

const context = createContext({});
const myError = runInContext('new Error()', context);
console.log(types.isNativeError(myError)); // true
console.log(myError instanceof Error); // falseconst { createContext, runInContext } = require('node:vm');
const { types } = require('node:util');

const context = createContext({});
const myError = runInContext('new Error()', context);
console.log(types.isNativeError(myError)); // true
console.log(myError instanceof Error); // false

相反,isNativeError() 对所有不是由原生错误构造函数返回的对象都返回 false。这包括那些是原生错误 instanceof 的值

const myError = { __proto__: Error.prototype };
console.log(util.types.isNativeError(myError)); // false
console.log(myError instanceof Error); // true 

util.types.isNumberObject(value)#

如果该值是数字对象(例如,通过 new Number() 创建),则返回 true

util.types.isNumberObject(0);  // Returns false
util.types.isNumberObject(new Number(0));   // Returns true 

util.types.isPromise(value)#

如果值是内置的 <Promise>,则返回 true

util.types.isPromise(Promise.resolve(42));  // Returns true 

util.types.isProxy(value)#

如果值是 <Proxy> 实例,则返回 true

const target = {};
const proxy = new Proxy(target, {});
util.types.isProxy(target);  // Returns false
util.types.isProxy(proxy);  // Returns true 

util.types.isRegExp(value)#

如果值是正则表达式对象,则返回 true

util.types.isRegExp(/abc/);  // Returns true
util.types.isRegExp(new RegExp('abc'));  // Returns true 

util.types.isSet(value)#

如果值是内置的 <Set> 实例,则返回 true

util.types.isSet(new Set());  // Returns true 

util.types.isSetIterator(value)#

如果值是为内置 <Set> 实例返回的迭代器,则返回 true

const set = new Set();
util.types.isSetIterator(set.keys());  // Returns true
util.types.isSetIterator(set.values());  // Returns true
util.types.isSetIterator(set.entries());  // Returns true
util.types.isSetIterator(set[Symbol.iterator]());  // Returns true 

util.types.isSharedArrayBuffer(value)#

如果值是内置的 <SharedArrayBuffer> 实例,则返回 true。这包括 <ArrayBuffer> 实例。通常情况下,期望同时测试两者;请参见 util.types.isAnyArrayBuffer()

util.types.isSharedArrayBuffer(new ArrayBuffer());  // Returns false
util.types.isSharedArrayBuffer(new SharedArrayBuffer());  // Returns true 

util.types.isStringObject(value)#

如果该值是字符串对象(例如,通过 new String() 创建),则返回 true

util.types.isStringObject('foo');  // Returns false
util.types.isStringObject(new String('foo'));   // Returns true 

util.types.isSymbolObject(value)#

如果值是通过在 Symbol 原始值上调用 Object() 创建的符号对象,则返回 true

const symbol = Symbol('foo');
util.types.isSymbolObject(symbol);  // Returns false
util.types.isSymbolObject(Object(symbol));   // Returns true 

util.types.isTypedArray(value)#

如果值是内置的 <TypedArray> 实例,则返回 true

util.types.isTypedArray(new ArrayBuffer());  // Returns false
util.types.isTypedArray(new Uint8Array());  // Returns true
util.types.isTypedArray(new Float64Array());  // Returns true 

另请参见 ArrayBuffer.isView()

util.types.isUint8Array(value)#

如果值是内置的 <Uint8Array> 实例,则返回 true

util.types.isUint8Array(new ArrayBuffer());  // Returns false
util.types.isUint8Array(new Uint8Array());  // Returns true
util.types.isUint8Array(new Float64Array());  // Returns false 

util.types.isUint8ClampedArray(value)#

如果值是内置的 <Uint8ClampedArray> 实例,则返回 true

util.types.isUint8ClampedArray(new ArrayBuffer());  // Returns false
util.types.isUint8ClampedArray(new Uint8ClampedArray());  // Returns true
util.types.isUint8ClampedArray(new Float64Array());  // Returns false 

util.types.isUint16Array(value)#

如果值是内置的 <Uint16Array> 实例,则返回 true

util.types.isUint16Array(new ArrayBuffer());  // Returns false
util.types.isUint16Array(new Uint16Array());  // Returns true
util.types.isUint16Array(new Float64Array());  // Returns false 

util.types.isUint32Array(value)#

如果值是内置的 <Uint32Array> 实例,则返回 true

util.types.isUint32Array(new ArrayBuffer());  // Returns false
util.types.isUint32Array(new Uint32Array());  // Returns true
util.types.isUint32Array(new Float64Array());  // Returns false 

util.types.isWeakMap(value)#

如果值是内置的 <WeakMap> 实例,则返回 true

util.types.isWeakMap(new WeakMap());  // Returns true 

util.types.isWeakSet(value)#

如果值是内置的 <WeakSet> 实例,则返回 true

util.types.isWeakSet(new WeakSet());  // Returns true 

已弃用的 API#

以下 API 已被弃用,不应再使用。现有的应用程序和模块应更新以寻找替代方法。

util._extend(target, source)#

稳定性:0 - 已弃用:请改用 Object.assign()

util._extend() 方法从未打算在 Node.js 内部模块之外使用。但社区还是发现并使用了它。

它已被弃用,不应在新代码中使用。JavaScript 通过 Object.assign() 提供了非常相似的内置功能。

util.isArray(object)#

稳定性:0 - 已弃用:请改用 Array.isArray()

Array.isArray() 的别名。

如果给定的 object 是一个 Array,则返回 true。否则,返回 false

const util = require('node:util');

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