node:util
node:util 提供了许多工具函数,
TIP
如果你想在浏览器环境也使用 node:util 里面的工具函数,可以使用 browserify/node-util 这个 NPM 包
注意 browserify/node-util 里面导出的函数并不完全和 node:util 一致,使用特定的函数前请检查是否支持
原型继承
inherits 是一个实现对象间原型继承的函数。
function Base() {
this.name = 'base';
}
Base.prototype.showName = function() {
console.log(this.name);
};
function Sub() {
this.name = 'sub';
}
inherits(Sub, Base);所构建的对象关系如下图所示:
接下来对二者实例化
var objBase = new Base();
objBase.showName(); // 'base'
var objSub = new Sub();
objSub.showName(); // 'sub'得到关系:
inspect
inspect 用于它可以将一个对象转换为字符串,显示对象的详细信息,函数签名如下,
export function inspect(object: any, showHidden?: boolean, depth?: number | null, color?: boolean): string;
export function inspect(object: any, options?: InspectOptions): string;InspectOptions 的类型定义
export interface InspectOptions {
/**
* If `true`, object's non-enumerable symbols and properties are included in the formatted result.
* `WeakMap` and `WeakSet` entries are also included as well as user defined prototype properties (excluding method properties).
* @default false
*/
showHidden?: boolean | undefined;
/**
* Specifies the number of times to recurse while formatting object.
* This is useful for inspecting large objects.
* To recurse up to the maximum call stack size pass `Infinity` or `null`.
* @default 2
*/
depth?: number | null | undefined;
/**
* If `true`, the output is styled with ANSI color codes. Colors are customizable.
*/
colors?: boolean | undefined;
/**
* If `false`, `[util.inspect.custom](depth, opts, inspect)` functions are not invoked.
* @default true
*/
customInspect?: boolean | undefined;
/**
* If `true`, `Proxy` inspection includes the target and handler objects.
* @default false
*/
showProxy?: boolean | undefined;
/**
* Specifies the maximum number of `Array`, `TypedArray`, `WeakMap`, and `WeakSet` elements
* to include when formatting. Set to `null` or `Infinity` to show all elements.
* Set to `0` or negative to show no elements.
* @default 100
*/
maxArrayLength?: number | null | undefined;
/**
* Specifies the maximum number of characters to
* include when formatting. Set to `null` or `Infinity` to show all elements.
* Set to `0` or negative to show no characters.
* @default 10000
*/
maxStringLength?: number | null | undefined;
/**
* The length at which input values are split across multiple lines.
* Set to `Infinity` to format the input as a single line
* (in combination with `compact` set to `true` or any number >= `1`).
* @default 80
*/
breakLength?: number | undefined;
/**
* Setting this to `false` causes each object key
* to be displayed on a new line. It will also add new lines to text that is
* longer than `breakLength`. If set to a number, the most `n` inner elements
* are united on a single line as long as all properties fit into
* `breakLength`. Short array elements are also grouped together. Note that no
* text will be reduced below 16 characters, no matter the `breakLength` size.
* For more information, see the example below.
* @default true
*/
compact?: boolean | number | undefined;
/**
* If set to `true` or a function, all properties of an object, and `Set` and `Map`
* entries are sorted in the resulting string.
* If set to `true` the default sort is used.
* If set to a function, it is used as a compare function.
*/
sorted?: boolean | ((a: string, b: string) => number) | undefined;
/**
* If set to `true`, getters are going to be
* inspected as well. If set to `'get'` only getters without setter are going
* to be inspected. If set to `'set'` only getters having a corresponding
* setter are going to be inspected. This might cause side effects depending on
* the getter function.
* @default false
*/
getters?: 'get' | 'set' | boolean | undefined;
/**
* If set to `true`, an underscore is used to separate every three digits in all bigints and numbers.
* @default false
*/
numericSeparator?: boolean | undefined;
}举个例子:
const obj = {};
Object.defineProperty(obj, 'hidden', {
enumerable: false,
value: 'foo'
});
obj.hidden // 'foo'
util.inspect(obj); // {}
util.inspect(obj, { showHidden: true }); // { hidden: 'foo' }对于日常使用来说,一个头疼的问题是 NodeJS 在控制台的输出会被折叠,可以通过 inspect 设置第三个参数,控制打印的深度。类型为 number | null
const deepObject = {
a: {
b: {
c: {
d: 1
}
}
}
}
console.log(deepObject) // depth 默认为 2
/*
{ a: { b: { c: [Object] } } }
*/
console.log(util.inspect(deepObject, false, null)) //=> depth 设置为 null 代表不对深度限制,打印全部
/*
{ a: { b: { c: { d: 1 } } } }
*/promisify & callbackify
promisify 将一个接受回调的函数转换为返回 Promise 的函数,callbackify 则相反
需要满足的条件
- 被
promisify的函数的回调函数需要在函数参数的最后一个位置 - 回调函数的第一个参数为错误对象
err,第二个参数为成功结果data
import util from "node:util";
import fs from 'fs'
const readFile = util.promisify(fs.readFile);
readFile('./child.js', 'utf-8').then(data => {
console.log({ data }) //=> content
}, err => {});
const callbackFunction = util.callbackify(readFile)
callbackFunction('./child.js', 'utf-8', (err, data) => {
console.log({ data }) //=> content
})debuglog & debug
用于输出调试信息 ,且 util.debuglog === util.debug 为 true,二者是等价的
// index.js
import util from "node:util";
const debug = util.debuglog('foo');
debug('Hello-from-foo');
console.log('end')默认情况下, debuglog() 创建的函数不会打印任何信息。要启用打印,需要设置NODE_DEBUG 环境变量,所以这在我们调试某些模块的时候特别有用
$ node index.js
end
$ NODE_DEBUG=foo node index.js
Hello-from-foo
end我们经常使用第三方包 - debug-js/debug 作为原生的替代品,其优势在于:
debug支持更灵活的命名空间方式,用:隔开,例如debug('app:db')debug支持颜色、格式化等更丰富的输出选项- 支持浏览器
deprecate
deprecate() 用来在函数被调用时显示方法废弃警告信息。例如:
// index.js
import { deprecate } from 'node:util'
const oldFunc = deprecate(() => {
console.log('hello')
}, 'oldFunc() is deprecated, use newFunc() instead');
oldFunc(); // 输出警告信息执行结果:
$ node index.js
hello
(node:16920) DeprecationWarning: oldFunc() is deprecated, use newFunc() instead
(Use `node --trace-deprecation ...` to show where the warning was created)TIP
除此之外,在标记函数过时的信息方面,通常我们会选择 TS 注释的形式,例如
/**
* @deprecated oldFunc() is deprecated, use newFunc() instead
*/
function oldFunc() {
//...
}这能够给用户更完善的 IDEA 提示
format
format 可以用来格式化字符串,它用法类似于C语言中的 printf()
const name = 'John';
const age = 20;
console.log(
util.format('Hello %s, you are %d', name, age) //=> Hello John, you are 20
)更多请查看官方文档
isDeepStrictEqual
isDeepStrictEqual 一个深度递归的严格比较两个值是否相等的方法
import { isDeepStrictEqual } from 'node:util'
let obj1 = {
a: 1,
b: {
c: 2
}
};
let obj2 = {
a: 1,
b: {
c: 2
}
};
console.log(
isDeepStrictEqual(obj1, obj2) //=> true
)MIMEParams
用于操作 mime 类型的字符串
import { MIMEType } from 'node:util';
const { params } = new MIMEType('text/plain;foo=0;bar=1');
for (const name of params.keys()) {
console.log(name);
}更多请查看官方文档
types
用于判断某个数据类型,例如:
import { types } from 'node:util'
types.isDate(new Date()); // Returns true
types.isWeakSet(new WeakSet()); // Returns true
types.isPromise(Promise.resolve(42)); // Returns true从 v15.3.0,types 作为 util/types 模块暴露,更多请查看官方文档
import types from 'node:utils/types'