Util#

稳定性:2 - 稳定

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.convertProcessSignalToExitCode(signal)#

  • signal <string> 信号名称(例如 'SIGTERM'
  • 返回: <number> 对应于 signal 的退出代码

util.convertProcessSignalToExitCode() 方法将信号名称转换为其对应的 POSIX 退出代码。按照 POSIX 标准,由信号终止的进程的退出代码计算公式为 128 + 信号编号

如果 signal 不是有效的信号名称,则会抛出错误。有关有效信号的列表,请参阅 signal(7)

import { convertProcessSignalToExitCode } from 'node:util';

console.log(convertProcessSignalToExitCode('SIGTERM')); // 143 (128 + 15)
console.log(convertProcessSignalToExitCode('SIGKILL')); // 137 (128 + 9)
const { convertProcessSignalToExitCode } = require('node:util');

console.log(convertProcessSignalToExitCode('SIGTERM')); // 143 (128 + 15)
console.log(convertProcessSignalToExitCode('SIGKILL')); // 137 (128 + 9)

这在处理进程以根据终止进程的信号确定退出代码时特别有用。

util.debuglog(section[, callback])#

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

util.debuglog() 方法用于创建一个函数,该函数根据 NODE_DEBUG 环境变量的存在,有条件地将调试消息写入 stderr。如果 section 名称出现在该环境变量的值中,则返回的函数运行方式类似于 console.error()。如果不是,则返回的函数是一个空操作。

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-bar');

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

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[, options]])#

  • 返回: <Function> 被封装以发出警告的已弃用函数。
  • 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 code
    const { 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-deprecationprocess.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:用于转换所有值(除了 BigIntObject-0)。BigInt 值将以 n 表示,没有用户定义的 toString 函数或 Symbol.toPrimitive 函数的对象将使用 util.inspect() 进行检查,选项为 { depth: 0, colors: false, compact: 3 }
    • %d:用于转换所有值(除了 BigIntSymbol)。
    • %i:对所有值使用 parseInt(value, 10)(除了 BigIntSymbol)。
    • %f:对所有值使用 parseFloat(value)(除了 Symbol)。
    • %j:JSON。如果参数包含循环引用,则替换为字符串 '[Circular]'
    • %oObject。对象的字符串表示形式,采用通用的 JavaScript 对象格式。类似于 util.inspect(),选项为 { showHidden: true, showProxy: true }。这将显示完整对象,包括不可枚举属性和代理。
    • %OObject。对象的字符串表示形式,采用通用的 JavaScript 对象格式。类似于不带选项的 util.inspect()。这将显示完整对象,不包括不可枚举属性和代理。
    • %cCSS。此说明符被忽略,并将跳过传递的任何 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 <integer> 可选,要捕获为调用点对象的帧数。默认值: 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 开始)。

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

    与访问 error.stack 不同,此 API 返回的结果不受 Error.prepareStackTrace 的干扰。

    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.columnNumber}`);
      });
      // 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.columnNumber}`);
      });
      // 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 来重建原始位置。如果 source map 不可用,原始位置将与当前位置相同。当启用 --enable-source-maps 标志时,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 可用的所有系统错误代码的映射。错误代码和错误名称之间的映射是与平台相关的。有关常见错误名称,请参阅 常见系统错误

    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 类语法和 extends 关键字。

    不建议使用 util.inherits()。请使用 ES6 classextends 关键字来获取语言级别的继承支持。还要注意,这两种风格在语义上是不兼容的(参考详情)。

    从一个 构造函数 继承原型方法到另一个构造函数。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!"
    

    使用 classextends 的 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 时递归的次数。这对于检查大型对象很有用。要递归到最大调用堆栈大小,请传递 Infinitynull默认值: 2
    • colors <boolean> 如果为 true,输出将使用 ANSI 颜色代码进行样式设置。颜色是可定制的。请参阅 自定义 util.inspect 颜色默认值: false
    • customInspect <boolean> 如果为 false,则 [util.inspect.custom](depth, opts, inspect) 函数不会被调用。默认值: true
    • showProxy <boolean> 如果为 trueProxy 检查将包括 targethandler 对象。默认值: false
    • maxArrayLength <integer> 指定格式化时包含的 Array<TypedArray><Map><WeakMap><WeakSet> 元素的最大数量。设置为 nullInfinity 以显示所有元素。设置为 0 或负数以不显示任何元素。默认值: 100
    • maxStringLength <integer> 指定格式化时包含的最大字符数。设置为 nullInfinity 以显示所有元素。设置为 0 或负数以不显示任何字符。默认值: 10000
    • breakLength <integer> 输入值跨多行拆分的长度。设置为 Infinity 以将输入格式化为单行(与将 compact 设置为 true 或任何大于 1 的数字组合使用)。默认值: 80
    • compact <boolean> | <integer> 将此项设置为 false 会导致每个对象键显示在新行上。如果文本长于 breakLength,它将换行。如果设置为数字,最内部的 n 个元素将合并在单行上,只要所有属性都适合 breakLength。短数组元素也会被组合在一起。有关更多信息,请参阅下面的示例。默认值: 3
    • sorted <boolean> | <Function> 如果设置为 true 或函数,则对象的所有属性以及 SetMap 条目在结果字符串中都会排序。如果设置为 true,则使用 默认排序。如果设置为函数,它将用作 比较函数
    • getters <boolean> | <string> 如果设置为 true,则检查 getter。如果设置为 'get',则仅检查没有对应 setter 的 getter。如果设置为 'set',则仅检查有对应 setter 的 getter。根据 getter 函数的不同,这可能会产生副作用。默认值: false
    • numericSeparator <boolean> 如果设置为 true,下划线将用于分隔所有 bigint 和数字中每三位数字。默认值: 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_45
    const { 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.stylesutil.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 使用的默认选项。这对于隐式调用 util.inspectconsole.logutil.format 等函数很有用。它应设置为一个包含一个或多个有效 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 array
    const { 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>

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

    默认情况下,深度严格相等包括对象原型和构造函数的比较。当 skipPrototypetrue 时,如果对象的可枚举属性是深度严格相等的,那么具有不同原型或构造函数的对象仍然可以被视为相等。

    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/plain
    const { MIMEType } = require('node:util');
    const myMIME = new MIMEType({ toString: () => 'text/plain' });
    console.log(String(myMIME));
    // Prints: text/plain
    

    mime.type#

    获取和设置 MIME 的 type 部分。

    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/javascript
    const { 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 的 subtype 部分。

    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/javascript
    const { 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 的 essence。此属性是只读的。使用 mime.typemime.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=value
    const { 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
    //   bar
    const { 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=xyz
    const { 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 baz
    const { 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[]> 参数字符串数组。默认值: 移除了 execPathfilenameprocess.argv
      • options <Object> 用于描述解析器已知的参数。options 的键是选项的长名称,值是接受以下属性的 <Object>
        • type <string> 参数类型,必须为 booleanstring
        • multiple <boolean> 此选项是否可以多次提供。如果为 true,则所有值将收集在一个数组中。如果为 false,则选项的值以最后一次为准。默认值: false
        • short <string> 选项的单字符别名。
        • default <string> | <boolean> | <string[]> | <boolean[]> 如果选项未出现在要解析的参数中,则分配给该选项的值。该值必须匹配 type 属性指定的类型。如果 multipletrue,则必须是一个数组。当选项确实出现在要解析的参数中时,不应用默认值,即使提供的值是虚值。
      • strict <boolean> 当遇到未知参数,或传递的参数与 options 中配置的 type 不匹配时,是否应抛出错误。默认值: true
      • allowPositionals <boolean> 该命令是否接受位置参数。默认值: 如果 stricttrue 则为 false,否则为 true
      • allowNegative <boolean> 如果为 true,允许通过在选项名称前加上 --no- 来显式将布尔选项设置为 false默认值: false
      • tokens <boolean> 返回已解析的令牌。这对于扩展内置行为(从添加额外的检查到以不同方式重新处理令牌)很有用。默认值: 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> 选项在参数中如何使用,例如 -f--foo
      • value <string> | <undefined> 参数中指定的选项值。对于布尔选项为未定义。
      • inlineValue <boolean> | <undefined> 选项值是否以内联方式指定,例如 --foo=bar
    • 位置令牌
      • value <string> 参数中位置参数的值(即 args[index])。
    • 选项终结器令牌

    返回的令牌按它们在输入参数中出现的顺序排列。在参数中出现多次的选项会为每次使用生成一个令牌。像 -xy 这样的短选项组会为每个选项展开一个令牌。因此 -xxx 生成三个令牌。

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

    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

    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_COLORNODE_DISABLE_COLORSFORCE_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 还提供诸如 italicunderline 等文本格式,您可以组合使用两者

    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'
    当 Node.js 在构建时开启 small-icu 选项时支持的编码#
    编码 别名
    '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]])#

  • 返回: <string>
  • 解码 input 并返回一个字符串。如果 options.streamtrue,则 input 末尾出现的任何不完整字节序列都会在内部缓存,并在下次调用 textDecoder.decode() 时输出。

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

    textDecoder.encoding#

    TextDecoder 实例支持的编码。

    textDecoder.fatal#

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

    textDecoder.ignoreBOM#

    如果解码结果将包含字节顺序标记 (BOM),则该值将为 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 中止时解决(resolve)的 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 原型的冻结对象。

    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 false
    const 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 24 开始,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() 对该值返回 true。对于来自不同 领域 (realm) 的错误,isNativeError() 返回 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); // false
    const { 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() 提供了非常类似的内置功能。

    提供自动迁移工具 (源代码)

    npx codemod@latest @nodejs/util-extend-to-object-assign
    

    util.isArray(object)#

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

    Array.isArray() 的别名。

    如果给定的 objectArray,则返回 true。否则,返回 false

    const util = require('node:util');
    
    util.isArray([]);
    // Returns: true
    util.isArray(new Array());
    // Returns: true
    util.isArray({});
    // Returns: false
    

    提供自动迁移工具 (源代码)

    npx codemod@latest @nodejs/util-is