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