Node.js Common Utilities
The util
module is a core module in Node.js that provides a collection of utility functions, aimed at enhancing the functionality of core JavaScript, which is often considered too minimalistic.
Here's how to use it:
const util = require('util');
util.callbackify
util.callbackify(original)
converts an async
function (or a function that returns a Promise
) into a callback-style function that follows the error-first convention, for example, placing a (err, value) => ...
callback as the last argument. In the callback, the first argument is the rejection reason (or null
if the Promise
is resolved), and the second argument is the resolved value.
Example
const util = require('util');
async function fn() {
return 'hello world';
}
const callbackFunction = util.callbackify(fn);
callbackFunction((err, ret) => {
if (err) throw err;
console.log(ret);
});
The above code outputs:
hello world
The callback function is executed asynchronously and has error stack trace capabilities. If the callback throws an exception, the process will trigger an 'uncaughtException' event. If not caught, the process will exit.
null
has a special meaning as an argument in the callback function. If the first argument of the callback is the reason for Promise rejection and it can be converted to a boolean false
, this value is wrapped in an Error object and can be accessed via the reason
property.
function fn() {
return Promise.reject(null);
}
const callbackFunction = util.callbackify(fn);
callbackFunction((err, ret) => {
// When the Promise is rejected with `null`, it is wrapped as an Error and the original value is stored in `reason`.
err && err.hasOwnProperty('reason') && err.reason === null; // true
});
original
is an async
function. This function returns a traditional callback function.
util.inherits
util.inherits(constructor, superConstructor)
is a function that implements prototype-based inheritance between objects.
JavaScript's object-oriented features are prototype-based, unlike the class-based approach common in other languages. JavaScript does not provide language-level features for object inheritance but achieves it through prototype copying.
Here, we will only introduce the usage of util.inherits
with an example:
var util = require('util');
function Base() {
this.name = 'base';
this.base = 1991;
this.sayHello = function() {
console.log('Hello ' + this.name);
};
}
Base.prototype.showName = function() {
console.log(this.name);
};
function Sub() {
this.name = 'sub';
}
util.inherits(Sub, Base);
var objBase = new Base();
objBase.showName();
objBase.sayHello();
console.log(objBase);
var objSub = new Sub();
objSub.showName();
//objSub.sayHello();
console.log(objSub);
We define a base object Base
and a Sub
object that inherits from Base
. Base
has three properties defined in the constructor and one function defined in the prototype. Inheritance is achieved using util.inherits
. The output is as follows:
base
Hello base
{ name: 'base', base: 1991, sayHello: [Function] }
sub
{ name: 'sub' }
Note: Sub
only inherits functions defined in the prototype of Base
, and properties or functions created inside the constructor of Base
are not inherited by Sub
.
At the same time, properties defined in the prototype will not be output as object properties by console.log
. If we uncomment the line objSub.sayHello();
, we will see:
node.js:201
throw e; // process.nextTick error, or 'error' event on first tick
^
TypeError: Object #<Sub> has no method 'sayHello'
at Object.<anonymous> (/home/byvoid/utilinherits.js:29:8)
at Module._compile (module.js:441:26)
at Object..js (module.js:459:10)
at Module.load (module.js:348:31)
at Function._load (module.js:308:12)
at Array.0 (module.js:479:10)
at EventEmitter._tickCallback (node.js:192:40)
util.inspect
util.inspect(object,[showHidden],[depth],[colors])
is a method that converts any object to a string, typically used for debugging and error output. It at least accepts one parameter, object
, which is the object to be converted.
showHidden
is an optional parameter. If set to true
, it will output more hidden information.
depth
indicates the maximum recursion level. If the object is complex, you can specify the level to control the amount of output information. If depth
is not specified, it defaults to recursing 2 levels. Setting it to null
means it will traverse the object without limit. If colors
is set to true
, the output will be formatted with ANSI color codes, which is usually used to display a more aesthetically pleasing effect in the terminal.
It is important to note that util.inspect
does not simply convert the object to a string directly, even if the object has defined a toString
method.
var util = require('util');
function Person() {
this.name = 'byvoid';
this.toString = function() {
return this.name;
};
}
var obj = new Person();
console.log(util.inspect(obj));
console.log(util.inspect(obj, true));
The result of running this code is:
Person { name: 'byvoid', toString: [Function] }
Person {
name: 'byvoid',
toString:
{ [Function]
[length]: 0,
[name]: '',
[arguments]: null,
[caller]: null,
[prototype]: { [constructor]: [Circular] } } }
util.isArray(object)
Returns true
if the given parameter "object" is an array, otherwise returns false
.
var util = require('util');
util.isArray([])
// true
util.isArray(new Array)
// true
util.isArray({})
// false
util.isRegExp(object)
Returns true
if the given parameter "object" is a regular expression, otherwise returns false
.
var util = require('util');
util.isRegExp(/some regexp/)
// true
util.isRegExp(new RegExp('another regexp'))
// true
util.isRegExp({})
// false
util.isDate(object)
Returns true
if the given parameter "object" is a date, otherwise returns false
.
var util = require('util');
util.isDate(new Date())
// true
util.isDate(Date())
// false (without 'new' returns a String)
util.isDate({})
// false
For more details, please visit https://nodejs.org/api/util.html to learn more.