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]])#

  • fn <Function> 被棄用的函式。
  • msg <string> 呼叫已棄用函式時顯示的警告訊息。
  • code <string> 棄用代碼。請參閱 已棄用 API 列表 以獲取代碼列表。
  • options <Object>
    • modifyPrototype <boolean> 當設為 false 時,在發出棄用警告時不會變更物件的原型。預設值:true
  • 回傳:<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。在發出警告後,封裝的函式會被呼叫,且不再發出警告。

如果相同的可選 code 被用於多次 util.deprecate() 呼叫,則該警告僅會針對該 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 的格式字串,該字串可以包含零個或多個格式指定符。每個指定符會被對應參數的轉換值所取代。支援的指定符如下:

  • %sString 將用於轉換除了 BigIntObject-0 以外的所有值。BigInt 值將以 n 表示,而沒有自定義 toString 函式或 Symbol.toPrimitive 函式的物件將使用 util.inspect() 進行檢查,並使用選項 { depth: 0, colors: false, compact: 3 }
  • %dNumber 將用於轉換除了 BigIntSymbol 以外的所有值。
  • %iparseInt(value, 10) 用於轉換除了 BigIntSymbol 以外的所有值。
  • %fparseFloat(value) 用於轉換除了 Symbol 以外的所有值。
  • %j:JSON。如果參數包含循環參照,則替換為字串 '[Circular]'
  • %oObject。帶有通用 JavaScript 物件格式化的物件字串表示。類似於帶有選項 { showHidden: true, showProxy: true }util.inspect()。這將顯示包含不可列舉屬性和代理的完整物件。
  • %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 可用的所有系統錯誤代碼的 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 類別語法和 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 的不可列舉 Symbol 和屬性會包含在格式化結果中。<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,它會在新行處換行。如果設為數字,只要所有屬性都符合 breakLength,內部最深 n 層的元素將會結合在同一行。短陣列元素也會分組在一起。更多資訊請參閱下方的範例。預設值:3
    • sorted <boolean> | <Function> 如果設為 true 或一個函式,結果字串中物件的所有屬性以及 SetMap 條目將會被排序。如果設為 true,則使用 預設排序。如果設為函式,則作為 比較函式 使用。
    • getters <boolean> | <string> 如果設為 true,則會檢查 getters。如果設為 'get',則僅檢查沒有對應 setter 的 getters。如果設為 'set',則僅檢查有對應 setter 的 getters。根據 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 中的顏色進行關聯的 map。

預設樣式和關聯顏色如下:

  • 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 還已 全域註冊,並且可以在任何環境中作為 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.logutil.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 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 的型別部分。

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 的子型別部分。

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 的本質。此屬性為唯讀。請使用 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() 的別名。

當使用 JSON.stringify() 序列化 MIMEType 物件時,會自動呼叫此方法。

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[]> 參數字串陣列。預設值:process.argv,移除了 execPathfilename
    • 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> 回傳解析後的 token。這對於擴充內建行為非常有用,例如新增額外檢查或以不同方式重新處理 token。預設值: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,可取得用於新增自定義行為的詳細解析資訊。回傳的 token 具有描述性的屬性:

  • 所有 token:
    • kind <string> 'option'、'positional' 或 'option-terminator' 之一。
    • index <number> 包含 token 的 args 元素索引。因此,token 的來源參數為 args[token.index]
  • 選項 token:
    • name <string> 選項的長名稱。
    • rawName <string> 選項在 args 中使用的形式,如 -f--foo
    • value <string> | <undefined> args 中指定的選項值。布林選項為 undefined。
    • inlineValue <boolean> | <undefined> 選項值是否為內聯指定,如 --foo=bar
  • 位置 token:
    • value <string> args 中位置參數的值(即 args[index])。
  • 選項終止符 token。

回傳的 token 順序為在輸入 args 中遇到的順序。在 args 中出現多次的選項會為每次使用產生一個 token。像 -xy 這樣的短選項群組會展開為每個選項一個 token。因此 -xxx 會產生三個 token。

例如,若要新增對 --no-color 這種否定選項的支援(allowNegative 在選項為 boolean 型別時支援),可以對回傳的 token 進行重新處理,以更改儲存的否定選項值。

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 Symbol,可以覆寫 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 還已 全域註冊,並且可以在任何環境中作為 Symbol.for('nodejs.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 實例支援的編碼。預設值: 'utf-8'
  • options <Object>
    • fatal <boolean> 若為 true,則解碼失敗會導致錯誤。當 ICU 被停用時,此選項不受支援(請參閱 國際化 (Internationalization))。預設值: 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#

若解碼結果包含位元組順序標記 (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 碼元 (code units) 數量。
    • 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> 被標記為可轉移(transferable),可與 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 中進行類型檢查的插件開發者有用。

可透過 require('node:util').typesrequire('node:util/types') 存取該 API。

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> 視圖(如 TypedArray 物件或 <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)#

若值為 async 函數,則傳回 true。這僅回報 JavaScript 引擎所見到的內容;特別是若使用了轉譯工具(transpilation tool),傳回值可能與原始程式碼不符。

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)#

若值為任何裝箱(boxed)的原始型別物件(例如由 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)#

若值為產生器函數(generator function),則傳回 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)#

若值為 模組命名空間物件 (Module Namespace Object) 的實例,則傳回 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() 對該值傳回 trueisNativeError() 對來自不同 領域 (realm) 的錯誤傳回 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 物件(藉由對 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